slice是array的一个视图。

slice本身是没有数据的,是对底层array的一个view。

s1和s2的值是多少?

1
2
3
4
5
6
7
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 := arr[2:6]

//s2取的是s1[3]和s1[4],但是s1[4]是不存在的
s2 := s1[3:5]

fmt.Println(s1, s2)

s1[4]也会被取到,因为slice是可以扩展的

slice的底层实现

ptr:slice在array中的起始位置
len:slice元素的长度
cap:slice在array上的起始位置到末尾的长度
*slice扩展时,只要长度(或者下标)不超过cap的位置即可扩展,其值为底层array的值。(只可向后扩展,不能向前扩展)

如何获取slice的len和cap

1
2
len := len(s1)
cap := cap(s1)

添加元素

1
2
3
4
5
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println(s3, s4, s5)
fmt.Println(arr)
  • 添加元素时如果长度超过了底层array的cap,系统会拷贝当前array,重新分配一个空间更大的array。原来的array如果没人使用后就会被垃圾回收机制回收。
  • 由于值传递的关系,append后必须使用一个变量来接收返回值。
    1
    s = append(s,val)

创建

1
var s []int  //Zero value for slice is null,也就是说我定义个s后,s==nil
  • cap是怎么扩展的?(怎么分配的?)
    答:当cap用尽后,都会将cap扩展为原来的两倍 cap = 2*cap
  • 如何创建一个规定长度的slice?
    1
    2
    3
    4
    //创建一个len为16的slice
    s := make([]int, 16)
    //创建一个len为10,cap为32的slice
    s := make([]int, 10, 32)

拷贝slice

1
copy(s2,s1)   //s2为拷贝到哪,s1为原slice

删除slice elements

没有直接操作的函数
思路:如需删除第3个元素,则新变量 = 前两个元素 + 第三个元素后面的所有元素

1
s2 = append(s2[:3], s2[4:]...)

注意:像s2[:3]这里面的中括号为半开半闭区间,前面为闭区间,后面为开区间。即前面为包含关系,后面为不包含关系。