其本身并不是数组,它指向底层的数组
作为变长数组的替代方案,可以关联底层数组的局部或全部
为引用类型
可以直接创建或从底层数组获取生成
使用len()获取元素个数,cap()获取容量
一般使用make()创建
如果多个slice指向相同底层数组,其中一个的值改变会影响全部
var s1 []int //[]是空的代表着是slice 如果是数字或者...就表示是数组
a := [10]int{}
fmt.Println(a)//输出10个0
s1 := a[5:10] //这里取索引为5 6 7 8 9的数组元素
fmt.Println(s1)
s2 := a[5:]
s3 := a[5:len(a)]
s4 := a[:5] //这里不会包含索引为5的元素
比较正式的方法
make([]T, len, cap)
其中cap可以省略,则和len的值相同
len表示存数的元素个数,cap表示容量
注意:当slice元素个数超出cap容量个数的时候,slice会重新分配一块内存空间给该slice,该内存空间是原先cap容量的2陪,原先内存地址会被弃用,所以指针要小心
s1 := make([]int,3,10)
fmt.Println(len(s1),cap(s1))//3 10
s1 := make([]int,3)
fmt.Println(len(s1),cap(s1))//3 3
Reslice
Reslice时索引以被slice的切片为准
索引不可以超过被slice的切片的容量cap()值
索引越界不会导致底层数组的重新分配而是引发错误
a := []bate{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
sa := a[2:5]
sb := a[3:11]//报错 越界了
Append
可以在slice尾部追加元素
可以将一个slice追加在另一个slice尾部
如果最终长度未超过追加到slice的容量则返回原始slice
如果超过追加到的slice的容量则将重新分配数组并拷贝原始数据
s1 := make([]int,3,6)
fmt.Println("%p", s1)
s1 = append(s1, 1, 2, 3)
fmt.Println("%v %p", s1, s1)//打印出内存地址和内容
s1 = append(s1, 1, 2, 3, 4)
fmt.Println("%v %p", s1, s1)//打印出内存地址和内容 这里内存地址和原先的不一样了,因为已经大于容量,重新分配内存地址了
a := []int{1, 2, 3, 4, 5, 6}
s1 := a[2:5]
s2 := a[1:3]
fmt.Println(s1, s2)//这里的索引为2的元素s1 s2都有
s1[0] = 9
fmt.Println(s1, s2)//这里的索引为2的元素s1 s2中都变为9 所以切片是引用类型
s3 = a[1:3]
s3 = append(s3,1,2,3,4,5,6,7,6,6,6,6)
s1[0] = 9
fmt.Println(s1, s2)//s1 s2 已经不同了 s3的append大出容量 给他重新的地址了 相当于新的空间
copy
s1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
s2 := []int{7, 8, 9}
copy(s1,s2)//s2拷贝到s1中
fmt.Println(s1)//前面三个元素被覆盖了
copy(s2,s1)//s1拷贝到s2中//s2中的 前三个元素变为1 2 3 后面多余的s1中的元素没有拷贝过来