Go 中的值、指针与引用语义

串起 Go 的值复制、指针共享以及 slice 和 map 等运行时共享结构,建立“表面像引用,底层仍有值复制”的统一心智。

#type / synthesis #status / growing #tech / dev #resource / go

[!info] related notes

Go 中的值、指针与引用语义

范围

这篇笔记覆盖 Go 里最容易让初学者混乱的一组问题:

  • 函数参数到底怎么传
  • 指针为什么能改原值
  • slice / map 为什么看起来像“引用传递”

为什么要放在一起理解

如果把这些概念拆开看,很容易得出错误结论:

  • “Go 都是值传递,所以不会共享”
  • “slice 是引用类型,所以不是值传递”

这两种说法都抓不住 Go 的真实模型。

关系与依赖

更稳的理解方式是:

  1. Go 传参默认是值复制
  2. 但被复制的“值”有时本身就携带对底层数据的引用信息
  3. 指针复制后仍指向同一地址
  4. slice 复制后,描述符被复制,但底层数组可能共享
  5. map 复制后,运行时结构句柄被复制,但底层数据仍共享

所以真正该问的不是“它是不是引用传递”,而是:

  • 被复制的那个值里,是否仍然指向共享底层数据

对比与易混淆点

  • 普通整数:复制后彼此独立
  • 指针:复制的是地址值,因此仍指向同一目标
  • slice:复制的是描述符,底层数组可能共享
  • map:复制的是运行时句柄,底层结构仍共享

一个实用判断方式

遇到“改了为什么影响外面”的问题时,先问:

  1. 这个类型本身是不是值复制
  2. 复制后的新值里,是否仍包含共享底层数据的入口

这样比背“引用类型列表”更稳。

创建于 2026/6/20 更新于 2026/6/20