本文档旨在引导你自主阅读 Go 1.21 的 slice 源码
把下面内容当作阅读源码前的准备清单与思考题。
推荐阅读
- Go Slices: usage and internals:官方视角的切片设计背景,建议先读以对齐术语。
- Go 1.18 扩容策略的变化 (GitHub Commit):官方改动说明与推导过程,理解扩容策略的关键来源。
核心结构与基础
在开始阅读代码前,请先思考并尝试在源码中找到以下问题的答案:
- 底层结构:slice 在底层是如何定义的?
- 零切片|空切片|nil 切片:切片的各种创建方式在底层上有什么区别?
- 切片截取:执行
t := s[2:4]时,底层发生了什么?是否发生了内存拷贝?
重点函数:growslice
这是切片扩容的核心逻辑,位于 src/runtime/slice.go。阅读时请关注:
- 扩容策略:
- 在 Go 1.18 之后,扩容阈值从 1024 变成了多少?
- 为什么不再是简单的“翻倍”?
- 内存对齐(Round Up):
- 扩容计算出的新容量(
newcap)就是最终申请的内存大小吗? - 寻找代码中关于
roundupsize的调用,理解它如何根据内存规格调整容量。
- 扩容计算出的新容量(
- 写屏障与内存拷贝:
- 扩容后旧数据是如何迁移到新内存的?(寻找
memmove)
- 扩容后旧数据是如何迁移到新内存的?(寻找