go数据类型-slice底层
切片的底层数据结构
有上篇string为基础了,能猜到slice肯定也有一个对应的struct。
在runtime的 slice.go中
type slice struct {
array unsafe.Pointer
len int
cap int
}
切片的本质是对数组的引用
len 表示当前已经存储的个数,cap表示容量。
切片的创建
-
根据数组创建
s := arr[0:31]
-
字面量:编译时插入创建数组的代码
s := []int{1, 2, 3}
-
make:运行时创建数组
slice := make([lint, 10)
切片的追加
扩容时,编译时转为调用 runtime.growslice()
有兴趣的可以看下源码,方法介绍也能看出一些逻辑。
直接小结:
1.如果期望容量大于当前容量的两倍就会使用期望容量
比如当前是3,期望9,那么即使翻倍也达不到要求,所以直接变成9.
2.如果当前切片的长度小于 1024,将容量翻倍
比如当前容量为3, 如果再加一个值,则容量直接变为 6.
3.如果当前切片的长度大于 1024,每次增加 25%
4.切片扩容时,并发不安全,注意切片并发要加锁,
因为扩容时候,会新创建一个数组,如果在这个过程中,并发访问可能会是访问老的数组。
因为数组必须是连续的存储空间,所以每次扩容,都会创建一个新的数组。