正文

基于 Go 1.19。

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

21.25

扩容的示例

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

slice3sliceslice12

在 1.18 版本以后,旧的切片容量小于 256 的时候,会进行 2 倍扩容。

实际扩容倍数

commit

大概意思是:

<10242>=10241.25

它还给了个表格,写明了不同容量下的增长因子:

starting capgrowth factor
2562.0
5121.63
10241.44
20481.35
40961.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