切片(slice)
地址长度容量地址长度容量长度len()cap()
var s = []int{1, 2, 3}
fmt.Println("长度:", len(s), "容量:", cap(s)) // 长度: 3 容量: 3

初始化

直接声明

nilnilnil切片
var s1 []int
fmt.Println(s1)        // []
fmt.Println(s1 == nil) // true

初始化列表

通过初始化列表得到切片,切片长度与容量等于初始化列表的元素个数。其本质是生成一个底层数组,然后让声明的切片指向该底层数组。

var s2 = []int{1, 2, 3}
s3 := []string{"我", "爱", "中", "国"}
fmt.Println(s2 == nil, s2, s3) // false [1 2 3] [我 爱 中 国]
fmt.Println(len(s3), cap(s3))  // 4 4

数组得到切片、切片再切片

切片通过两个下标来界定,即一个上界和一个下界,二者以冒号分隔:

a[low : high]

它会选择一个半开区间,包括第一个元素,但排除最后一个元素。
切片下界的默认值为 0,上界则是该切片的长度。

var a = [...]int{0, 1, 2, 3, 4, 5}
var s4 = a[0:3]
fmt.Println(s4) // [0 1 2]
var s5 = a[:]
fmt.Println(s5) // [0 1 2 3 4 5]
s5 = s4[1:]
fmt.Println(s5) // [0 1 2]

切片容量是切片第一个元素到底层数组最后一个元素的长度。

var s6 = a[2:4]
fmt.Println(s6, cap(s6)) // [2 3] 4

切片可以再切片,再切片的上界取决于原切片的容量。

var s7 = s6[1:3]
fmt.Println(s7, cap(s7)) // [3 4] 3

上述示例中的切片s4~s7的底层数组都是 a,更改切片的元素会修改其底层数组中对应的元素,与它共享底层数组的切片都会观测到这些修改。

s6[1] = 10
fmt.Println(s7) // [10 4]

切片不能和切片比较

nils == nils1 == s2