章节摘要:并发程序最难查的 bug 往往不是"算错",而是"数据被谁改了"。本章把 Go 的数据组织讲透——结构体怎么建档案、接口怎么定岗位、指针怎么传地址、泛型怎么发通用工牌、反射怎么做证件扫描。每一节都直指一个可考核的知识点,学完后你能预判一段数据在传递、复制、比较时的确切行为,这正是第 3 章并发数据流的安全前提。
把一个值传给函数、发给 channel、存进 map,它经历了什么?值被复制了吗?改一处会动另一处吗?空指针为什么在凌晨三点才炸?本章用五节回答这类问题。调度夜班的比喻在本章继续:员工要建档(结构体)、定岗(接口)、留联系方式(指针),档案系统清楚了,排班才不会乱。
金句:并发 bug 的第一现场几乎都不在并发代码里,而在"你以为复制了、其实共享了"的那一行。
五节共用一条主轴——值语义与指针语义。结构体先定下"数据长什么样",方法讨论"谁来操作数据";接口在能力层面抽象操作;指针揭示数据何时被共享;泛型把"类型不同、逻辑相同"的重复代码收拢;反射则把前四节的静态规则推迟到运行时处理。前四节循序渐进,第五节是进阶选学,但管理配置类代码时绕不开。
+---------------------+ | 2.1 结构体 2.2 接口 | | (形状) (能力) | +----------+----------+ | 2.3 指针(共享与复制) | +----------+----------+ | 2.4 泛型 2.5 反射 | | (编译期抽象)(运行时自省)| +---------------------+
var _ Shape = Circle{} 在编译期验证接口实现,并说明它为什么比等到调用处才发现问题好。前置:第 1 章的全部内容,尤其是 1.4 的多返回值与包可见性——本章示例默认你已掌握。零基础跳章的读者,至少先回看 1.3 的零值概念。
后续:第 3 章的 channel 只能传一种类型的值、锁保护的是共享数据、"通过通信共享内存"的前提都是本章的值与指针规则;第 4 章排查数据竞争时,判断"共享"的依据就是 2.3 节。本章学得越扎实,并发章越像把已知规则换个场景复述一遍。