Slice的数据结构
切片是对数组的一个连续片段的引用,所以切片是一个引用类型,一个长度可变的数组。 源码中的数据结构定义如下:
源码位置: src/runtime/slice.go#L22
|
|
创建切片
创建方式
|
|
创建逻辑
|
|
- 根据slice的类型和长度以及容量,计算出所需要的内存空间大小,
- 如果合法则调用
mallocgc
函数申请相应的连续内存并返回首地址,
下面来看一下是如何计算所需要的内存大小的
src\runtime\internal\math\math.go
|
|
追加元素
append()
|
|
追加元素流程如下:
- 计算当前slice长度i0与追加元素的长度总和i1,若i1 < i0(追加后的slice长度小于当前的slice长度),则直接抛出异常
- 若当前切片容量为0,则将容量改为追加元素的长度
- 循环遍历增加容量,
- 若追加的元素长度小于阈值(v1.18之前是1024,从v1.18开始改为256),则容量成倍增长,
- 否则容量每次增加1/4,(注:v1.18开始计算逻辑改为 m = (m + 3 * threshold) / 4) ,
- 创建新的切片,并将当前切片拷贝到新的切片中,返回新的切片
- 将追加的元素存储到新的切片指定位置
切片的扩容逻辑:
- 原cap扩充一倍,即doublecap
- 如果指定cap(追加元素后的切片长度) 大于 doublecap,则取cap,否则如下:
-
- cap 小于1024,取doublecap
-
- 每次增长 1/4,直至不小于cap
-