切片的声明

Go

切片的长度和容量

slen(s)cap(s)

切片追加元素后长度和容量的变化

append 函数

Goappend
append
append

下面我们一起看看源码是怎么实现的。

切片的源代码学习

Gosrc/runtime/slice.gogo1.16.7

切片的结构体

切片作为数组的引用,有三个属性字段:指向数组的指针、长度和容量。

切片的扩容

sliceappendsliceslicecaplenappendruntime.growslice

我们这里只放出基本的扩容规则的代码解析,如果对内存对齐、数据拷贝等感兴趣,可自行查看对应的源码。

基本扩容规则

从源码来看,实际上可以整理出几个规则:

append*2
append1/4

总结

切片是一个结构体,保存着切片的容量,长度以及指向数组的指针(数组的地址)。

从源码来看,当一个切片进行扩容时,会进行 growslice,这是一个花销较大的操作,在日常开发中,如果能明确知道切片的长度或者容量时,我们需要在初始化的时候声明,避免切片频繁扩容而带来的花销。