Go基础(四)切片

80 阅读1分钟

切片本身一个结构体,由指针、len和cap组成 切片的 地址跟数组首元素的地址是两码事

type slice struct {
    array unsafe.Pointer
    len int 
    cap int
}

slice.png

切片的地址跟数组的首元素的地址是两码事 ,当&slice的时候,取到的是属性array的地址,

//数组地址
arrays := [2]int{}
fmt.Println(unsafe.Pointer(&arrays))
fmt.Println(&arrays[0])

//切片地址
ints := make([]int, 2)
fmt.Println(unsafe.Pointer(&ints))
fmt.Println(&ints[0])

image.png

切片初始化

var s []int
s = []int{}              //初始化,len=cap=3
s = make([]int, 3)       //初始化,len=cap=3
s = make([]int, 3, 5)    //初始化,len3,cap=5
s = []int{1, 2, 3, 4, 5} //初始化,len=cap=5
s2d := [][]int{
   {1}, {2, 3}, //二维数组各行的列数相等,但二维切片各行的len可以不等
}

append

  • 切片相对于数组最大的特点就是可以追加元素
  • 追加的元素放到预留的内存空间里,同时len+1
  • 如果预留空间已用完,则会重新申请一块更大的内存空间 capacity变成之前的2倍(cap<1024)或1.25倍(1024<cap)。把原内存空间的数据拷贝过来,在新内存空间上执行append操作。

截取子切片

  • s:=make([]int,3,5)//le=3,cap=5
  • sub_slice=s[1:3] //len=2,cap=4
  • 刚开始,子切片和母切片共享底层的内存空间,修改子切片会反映到母切片上,在子切片上执行append会把新元素放在母切片上的预留内存空间上。
  • 当子切片不断执行append,消耗完了母切片预留内存空间,子切片跟母切片就会发生内存分离,此后两个切片没有任何关系。

sub_slice.png