Golang---基本类型(slice)
摘要: 今天我们来学习 Golang 中的一个基本的数据结构 slice, 这个和 C++ 中的 vector 容器思想基本一致,是一个容量可变的数组,那我们就来看下它和 array 的区别和联系,并对其中的典型操作给出分析。
数据结构

// StringHeader is the runtime representation of a string. // It cannot be used safely or portably and its representation may // change in a later release. // Moreover, the Data field is not sufficient to guarantee the data // it references will not be garbage collected, so programs must keep // a separate, correctly typed pointer to the underlying data. type StringHeader struct { Data uintptr Len int } // stringHeader is a safe version of StringHeader used within this package. type stringHeader struct { Data unsafe.Pointer Len int } // SliceHeader is the runtime representation of a slice. // It cannot be used safely or portably and its representation may // change in a later release. // Moreover, the Data field is not sufficient to guarantee the data // it references will not be garbage collected, so programs must keep // a separate, correctly typed pointer to the underlying data. type SliceHeader struct { Data uintptr Len int Cap int } // sliceHeader is a safe version of SliceHeader used within this package. type sliceHeader struct { Data unsafe.Pointer Len int Cap int }
通过上面的结构体,我们可以把 slice 看成一片连续的内存空间加上长度与容量的标识。
slice 和 array
与其它语言一样, slice 是 长度可变的数组,我们其实可以把切片看做是对数组的一层简单封装,因为在每个切片的底层数据结构中,一定会包含一个数组。数组可以被叫做切片的底层数组,而切片也可以被看做是对数组的某个连续片段的引用。
slice 的扩容
这里我们用 append 来向切片追加元素,我们首先会先对切片结构体进行解构获取它的数组指针、大小和容量,如果在追加元素后切片的大小大于容量,那么就会调用 runtime.growslice 对切片进行扩容,扩容就是为切片分配一块新的内存空间并将原切片的元素全部拷贝过去,具体代码如下:

func growslice(et *_type, old slice, cap int) slice { newcap := old.cap doublecap := newcap + newcap if cap > doublecap { newcap = cap } else { if old.len < 1024 { newcap = doublecap } else { for 0 < newcap && newcap < cap { newcap += newcap / 4 } if newcap <= 0 { newcap = cap } } }
总结上述代码:1:如果期望容量大于当前容量的两倍就会使用期望容量;
2;如果当前切片的长度小于 1024 就会将容量翻倍;
3:如果当前的切片长度大于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量;
参考资料:
https://draveness.me/golang/docs/part2-foundation/ch03-datastructure/golang-array-and-slice
https://time.geekbang.org/column/article/14106
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
2019-09-03 one_day_one_linuxCmd---netstat命令
2019-09-03 docker---Dockerfile编写