Go 将常用的数据结构数组(array)、切片(slice)、映射(map)实现为内置类型。可以利用 array 在列表中进行多个值的排序,或者使用更加灵活的:slice。字典或哈希类型同样可以使用,在 Go 中叫做 map。
1、array
数组定义
array 定义
[n]<type>
,n 为数组长度,长度是类型的一部分,定义后不能改变数组大小;<type>
为数组元素类型,对数组的存取和 C 语言一样,都是通过[ ]
加索引来完成。var arr [10]int // 定义长度为 10 的整型数组 arr[0] = 15 // 赋值 arr[9] = 33 ib := arr[0] // 读取
数组初始化
按照 Go 固定,声明的变量未初始化是默认赋值为其类型的 0。数组也一样,未初始化的数组自动赋值为 0。数组的初始化可以在声明时使用大括号加值来完成,如果每个元素都给定初值,可以省略大小使用
...
来代替,则编译器会自动计算数组大小。var a0 [10]int // 初始化为 0 a := [3]int{1, 2, 4} // 声明并初始化话 // 等价于 a := [...]int{1, 2, 4} /* 多维数组 */ b := [2][2]int{ [2]int{1, 2}, [2]int{3, 4} } // 等价于 b := [2][2]int{ [...]int{1, 2}, [...]int{3, 4} } // 2010-10-27 后的新版本中可以使用下面更简单的形式 b := [2][2]int{ {1, 2}, {3, 4}}
注意:数组是值类型的:将一个数组赋值给另一个数组,会复制所有的元素。尤其是当向函数内传递一个数组的时候,它会获得一个数组的副本,而不是数组的指针。
2、slice
slice 与 array 接近,但是在新的元素加入的时候可以增加长度。 slice 总是指向底层的一个 array。 slice 是一个指向 array 的指针,这是其与 array 不同的地方; slice 是引用类型, 这意味着当赋值某个 slice 到另外一个变量,两个引用会指向同一个 array。如果一个函数需要一个 slice 参数,在其内对 slice 元素的修改也会体现在函数调用者中,这和传递底层的 array 指针类似。
slice 创建
slice 可以使用内置函数 make 创建。它总是与一个固定长度的 array 成对出现。slice 与底层的 array 并无区别。
sl := make([]int, 10) // 创建保存有 10 个元素的 slice var arr [m]int // 创建数组,假设 m > 4 slice := arr[0:n] //创建指向此数组的 slice,长度为 n, 索引为:0 ~ n-1 /* 长度和容量 */ len(slice) == n cap(slice) == m len(arr) == cap(arr) == m /* 选择一定区间元素创建 slice */ sl1 := arr[1:5] // 索引为 1 ~ 4 sl2 := arr[:5] // 索引为 0 ~ 4 sl3 := arr[2:] // 索引为 2 ~ m-1 sl4 := arr[:] // 索引为 0 ~ m-1
给定一个 array 或者其他 slice,一个新 slice 通过
a[i:j]
的方式创建。这会创建一个新的 slice,指向变量 a,索引为 i~ j-1 (半闭半开区间)。长度为 j - i。省略 i 则默认索引从 0 开始,省略 j 则默认索引结束于数组最后一个元素,i 和 j 都省略则 slice 取数组全部元素。i 和 j 都不能超出数组索引的范围,否则会出现运行时错误。扩展 slice
扩展 slice 可以使用内建函数 append 和 copy。
来自文档的描述:
函数 append 向 slice s 追加零值或其他 x 值,并且返回追加后的新的、与 s 有相同类型的 slice。如果 s 没有足够的容量存储追加的值, append 分配一个足够大的、新的 slice 来存放原有 slice 的元素和追加的值。因此,返回的 slice 可能指向不同的底层 array。s0 := []int{0, 0} s1 := append(s0, 2) // 追加一个元素 s2 := append(s1, 3, 5, 7) // 追加三个元素 s3 := append(s2, s0...) // 追加一个 slice,**注意此处的三个点**
函数 copy 从源 slice src 复制元素到目标 dst,并且返回复制的元素的个数。源和目标可能重叠。复制的 数量是 len(src) 和 len(dst) 中的最小值。
var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7} var s = make([]int, 6) n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5},多余的不复制 n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
3、map
Go 将 map 作为内建类型。一般定义 map 的格式为:
map[<key type>]<value type>
例如定义一个map 表示每月对应的天数:
monthdays := map[string]int {
"Jan": 31, "Feb": 28, "Mar": 31,
"Apr": 30, "May": 31, "Jun": 30,
"Jul": 31, "Aug": 31, "Sep": 30,
"Oct": 31, "Nov": 30, "Dec": 31, ← 逗号是必须的
}
只声明一个 map 而不进行初始化时,需要使用内置函数 make。如
monthdays := make(map[string]int)
对 map 的存取使用方括号加键的形式:
monthdays["Undecim"] = 30 // 添加一个元素
monthdays["Feb"] = 29 // 修改值
jan := monthdays["Jan"] // 取键为 "Jan" 的值
检验 map 中是否存在某个键,可以使用逗号 ok 形式:
val, ok := monthdays["Jan"] // 若键 "Jan" 存在,ok == true
删除 map 中的某个元素,使用 delete(map, key)
。
delete(monthdays, "Mar") // 删除键为 "Mar" 的元素
4、遍历 array、slice、map
可以使用 range 对 array、 slice、 string 或者 map 进行循环遍历,每次调用,它都会返回一个键和对应的值。
// 计算一年的天数
// 使用 range 对 map 进行遍历
year := 0
for _, days := range monthdays { // 键没有使用,因此用 _, days
year += days
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
有疑问加站长微信联系(非本文作者)