slice
type slice struct {
array unsafe.Pointer
len int
cap int
}
slice由以上三部分组成,每个占8字节,所以一个slice占24字节。
至于每个的含义很明显不在赘述。len()和cap()函数可以查看相应的字段.
创建,初始化,访问
创建方式有两种
- make
make([]int,3,5)
make()比new()函数多一些操作,new()函数只会进行内存分配并做默认的赋0初始化,而make()可以先为底层数组分配好内存,然后从这个底层数组中再额外生成一个slice并初始化。另外,make只能构建slice、map和channel这3种结构的数据对象,因为它们都指向底层数据结构,都需要先为底层数据结构分配好内存并初始化。
make返回的是引用,而new返回的是指针.
- 赋值创建
color_slice := []string{"red","blue","black","green"}
//这种分配方式会时之后的字面量从100开始
color_slice := []string{99:"abc"}
关于初始化
TODO
访问
slice底层是数组,所以访问实际上是对数组的访问.slice能被访问的范围只能是lenth之内的.尝试读取或者写入会报错.
b:=make([]int,3,5)
b[0]=1
b[1]=2
b[2]=3
//err
fmt.Println(b[4])
fmt.Println(len(b))
nil silce和空slice
当声明一个slice没有初始化时,
var nil_slice []int
它的内部结构是这样的
ptr | len | cap |
---|---|---|
nil | 0 | 0 |
当创建一个空slice
empty_slice := make([]int,0)
empty_slice := []int{}
ptr | len | cap |
---|---|---|
addr | 0 | 0 |
切片赋值的一些操作
对于切片赋值,共享数组,slice变化这些不在赘述。
看下边一个
b:=make([]int,5,10)
b[0]=1
b[1]=2
b[2]=3
b[3]=4
c := b[1:3:6]
最后一条c是一个len=2,cap=6-1=5的切片。
像之上的赋值,第三个数不能超出原slice的cap,第二个数不能超过len.
append()
TODO
slice当做参数传给
Go中函数的参数是按值传递的。
虽然slice实际上包含了3个属性,它的数据结构类似于[3/5]0xc42003df10
.当向函数中传递一个slice时,传入一个副本,所以传递给函数的副本仍然指向源slice的底层数组。
如果函数内部对slice进行了修改,有可能会直接影响函数外部的底层数组,从而影响其它slice。但并不总是如此,例如函数内部对slice进行扩容,扩容时生成了一个新的底层数组,函数后续的代码只对新的底层数组操作,这样就不会影响原始的底层数组。
网友评论