Go中容器的值/引用语义取决于容器自身类型:数组是值类型,赋值时复制全部元素;切片、map、chan是引用类型,赋值时共享底层数据。
Go 中的值类型在容器中遵循严格的复制语义,但具体表现取决于容器本身是值类型还是引用类型。关键不是“容器里装的是值类型”,而是“这个容器自身是不是值类型”。
声明为 [3]int 的数组,赋值或传参时会完整复制全部元素。两个数组变量互不影响:
== 即可,因为它是逐元素比对的值比较切片类型 []int 本身是值类型(结构体:指向底层数组的指针 + 长度 + 容量),但它的行为更接近引用:
s2 := s1 后,s1 和 s2 共享同一底层数组s1[0] = 99 会导致 s2[0] 也变成 99(只要没触发扩容)它们的变量存储的是内部结构的指针,所以:
m2 := m1 后,对 m2["k"] 的写入会反映在 m1 中ch2 发送数据,ch1(若与 ch2 是同一通道变量)能接收make 初始化,否则 panic容易混淆的一点是:“切片里存 int,所以是值传递”——其实无关元素类型,只看容器本身的实现机制:
真正决定是否复制的,是容器头(header)如何被传递,而不是里面装什么基本上就这些。理解容器自身的类型归属,比纠结“里面存的是啥”更能避免 bug。