正文
基于 Go 1.19。
go 的切片我们都知道可以自动地进行扩容,具体来说就是在切片的容量容纳不下新的元素的时候, 底层会帮我们为切片的底层数组分配更大的内存空间,然后把旧的切片的底层数组指针指向新的内存中:

21.25
扩容的示例
我们先通过一个简单的示例来感受一下切片扩容是什么时候发生的:
slice3sliceslice12

在 1.18 版本以后,旧的切片容量小于 256 的时候,会进行 2 倍扩容。
实际扩容倍数
commit
大概意思是:
<10242>=10241.25
它还给了个表格,写明了不同容量下的增长因子:
| starting cap | growth factor |
|---|---|
| 256 | 2.0 |
| 512 | 1.63 |
| 1024 | 1.44 |
| 2048 | 1.35 |
| 4096 | 1.30 |
1024210241.25
growslice 实现
growsliceruntime/slice.go
growslice
oldPtrnewLen= oldLen + numoldCapnumetelement type
oldLen + num
growslice 实现步骤
et.size == 0newLennewLen
注意:这个函数只是实现扩容,新增的元素没有在这个函数往切片中追加。
growslice 源码剖析
说明:
newLen < 0et.size == 0capmemnewLennewcap
总结
2growslice25621.25