golang语言 数组和切片
数组
数组是值,将一个数组变量赋值给另一个变量会复制其所有元素。将数组传入函数会复制其所有元素。可以传数组指针,但切片是更好的做法
数组的大小是其类型的一部分。类型 [10]int 和 [20]int 是不同的。长度必须为常量
长度为零的数组的尺寸为零;元素类型尺寸为零的任意长度的数组类型的尺寸也为零。
数组元素可以取址 &a[3]
可以通过数组指针p来访问和修改数组中的元素,p[i]等价于(*p)[i],如果该指针是nil指针,则panic
可以通过数组指针来派生切片,如果该指针是nil指针,即使派生操作下标为0,也将panic
for range nil值的数组指针,若第二个迭代变量被忽略或舍弃,迭代 len(数组) 次,否则panic
切片
切片操作不能超过底层数组的大小,即不能超过cap
切片元素可以取址 &s[2]
复制切片复制的是底层的结构体,切片引用的数组没有被复制
与任意类型的nil值一样,我们可以用 []int(nil) 类型转换表达式来生成一个对应类型slice的nil值。
声明但未初始化的切片为nil,nil值的切片没有底层数组,长度和容量都是0。
也有非nil值的slice的长度和容量也是0的,例如 []int{} 或 make([]int, 3)[3:] 。
slice不能比较,唯一合法的比较操作是和nil比较
除了和nil进行比较外,nil值的slice的行为和其他长度为0的slice一样
[]int(nil)[:] // 可以对nil值的切片使用切片操作,但下标值必须都为0,结果是nil值的切片
make([]int, 3, 5) 等价于 new([5]int)[0:3],后者是通过数组指针来派生切片
append可能会分配新的底层数组,可以安全地作用于nil值的slice
s0 := []int{0, 0}
s1 := append(s0, 2) // 追加单个元素 s1 == []int{0, 0, 2}
s2 := append(s1, 3, 5, 7) // 追加多个元素 s2 == []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...) // 追加一个切片 s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
s4 := append(s3[3:6], s3[2:]...) // 追加重复切片 s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
var b []byte
b = append(b, "bar"...) // 特殊:追加字符串的字节值 b == []byte{'b', 'a', 'r' }
var t []interface{}
t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"}
copy 将切片元素从来源 src 复制到目标 dst 并返回复制的元素数量。
被复制的元素数量为 len(src) 与 len(dst) 中较小的那个。
特别的,copy 可以赋值字符串的字节到 []byte 里。
var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6)
var b = make([]byte, 5)
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}
n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello") 特殊:复制字符串的字节
var s = []int{0, 1, 2, 3, 4, 5 }
copy(s[2:], s) // s == []int{0, 1, 0, 1, 2, 3}
数组和切片字面量
在数组中每个元素都有与之对应的整数下标来标明它的位置。
带键的元素使用该键作为它的下标;键必须为常量整数表达式。
无键的元素使用上一个元素的下标加一。若第一个元素无键,则它的下标为零。
s := [...]int{ 1, 'a':2, 3} //len(s) == 99
c := []int{
2 : 'a',
0 : 'b',
'c', // 1:'c'
'd', // 2:'d' 这行报错
}
最后一个元素如果和 } 不在同一行,那么不能省略后面的逗号
slice和map,未初始化和初始化但值为空,是不同的:
p1 := &[]int{} // 初始化的空slice,值是 []int{} 可对字面量取地址
p2 := new([]int) // 未初始化的slice,值是nil
p3 := []int(nil) // 未初始化的slice,值是nil
对于数组或数组指针或切片类型的变量a,
a[low:high:max] 操作会得到一个slice:a[low:high],且容量为max-low
这种形式的切片操作,只有low可以省略