Go 中的值、指针与引用语义
串起 Go 的值复制、指针共享以及 slice 和 map 等运行时共享结构,建立“表面像引用,底层仍有值复制”的统一心智。
#type / synthesis
#status / growing
#tech / dev
#resource / go
[!info] related notes
- 所属 MOC: Go 类型系统与抽象 MOC
- 相关概念: Go 指针, Go Slice, Go Map
Go 中的值、指针与引用语义
范围
这篇笔记覆盖 Go 里最容易让初学者混乱的一组问题:
- 函数参数到底怎么传
- 指针为什么能改原值
- slice / map 为什么看起来像“引用传递”
为什么要放在一起理解
如果把这些概念拆开看,很容易得出错误结论:
- “Go 都是值传递,所以不会共享”
- “slice 是引用类型,所以不是值传递”
这两种说法都抓不住 Go 的真实模型。
关系与依赖
更稳的理解方式是:
- Go 传参默认是值复制
- 但被复制的“值”有时本身就携带对底层数据的引用信息
- 指针复制后仍指向同一地址
- slice 复制后,描述符被复制,但底层数组可能共享
- map 复制后,运行时结构句柄被复制,但底层数据仍共享
所以真正该问的不是“它是不是引用传递”,而是:
- 被复制的那个值里,是否仍然指向共享底层数据
对比与易混淆点
- 普通整数:复制后彼此独立
- 指针:复制的是地址值,因此仍指向同一目标
- slice:复制的是描述符,底层数组可能共享
- map:复制的是运行时句柄,底层结构仍共享
一个实用判断方式
遇到“改了为什么影响外面”的问题时,先问:
- 这个类型本身是不是值复制
- 复制后的新值里,是否仍包含共享底层数据的入口
这样比背“引用类型列表”更稳。