golang源码分析源码分析–slice
切片基础概念切片基础概念:
切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。(注意:切片传递的是指针的拷贝值,所以可以在函数里面修改
指针指向的值,对外有影响)
切片的自动增长是通过append()函数来实现的
切片的底层内存也是在连续块中分配底层内存也是在连续块中分配的,所以切片还能获得索引,迭代以及为垃圾回收优化的好处。
源码分析源码分析:
结构体定义结构体定义
type slice struct {
array unsafe.Pointer
len int
cap int
}
slice的结构体包含三个参数,指针,长度,容量
所以传递一个切片切片需要24字节的内存:指针字段需要8字节,长度和容量字段分别需要8字节。
切片作为函数传递需要注意的地方切片作为函数传递需要注意的地方:
1.切片作为函数的参数在函数内改变值切片作为函数的参数在函数内改变值
切片作为参数可以节省空间,但是需要注意的是切片传递过去的值为指针,所以在函数中改变切片指向的值,在函数外也会有
影响,这是由切片结构体内存储的指针特性决定的
func changevalue(arr []int){
arr[0] = 2
fmt.Println(&arr[0])
}
func main() {
arr:=make([]int,0,2)
arr = append(arr,1)
fmt.Println(arr)
changevalue(arr)
fmt.Println(arr)
fmt.Println(&arr[0])
}
输出
[1] 0xc0000601b0
[2] 0xc0000601b0
2.切片在函数中的切片在函数中的append操作操作
append未在源码内找到实现方式,但是append的作用如下:
append函数将元素追加到slice的结尾,若切片还有生效的容量,则值直接追加到连续内存的后面。
若追加的值得数目大于切片的原容量,则申请一个新的底层数组,append返回更新的slice。
要注意,切片作为参数在函数中传递本质是是值传递,特殊点是它的值中有一个指针要注意,切片作为参数在函数中传递本质是是值传递,特殊点是它的值中有一个指针
不改变值得方式,append追加不改变函数外面的值,PS:哪怕追加至更改内存
func appendarrNoChange(arr []int){
arr = append(arr,2)
fmt.Println(&arr[0])
}
func main() {
arr:=make([]int,0,2)
arr = append(arr,1)
fmt.Println(arr)
appendarrNoChange(arr)
fmt.Println(arr)
fmt.Println(&arr[0])
}
[1] 0xc0000601b0
[1] 0xc0000601b0
func appendarrNoChange(arr []int){