标准答案
- 小型不可变值用值接收者可以表达复制语义,大结构或需要修改状态时通常用指针。
- 包含 Mutex、Once 等同步字段的结构体不应随意复制,否则会复制同步状态。
- 指针共享会引入数据竞争和生命周期问题,不能只因减少复制就全部使用指针。
- 方法集不同会影响类型是否满足接口,需同时检查值和指针形式。
题目解析
值接收者复制结构体,适合小型值对象和明确的复制语义;指针接收者共享对象并允许修改,适合大结构或状态对象。但复制可能复制 slice/map 指针、Mutex 和其他同步字段,不能只看字节大小。
指针减少复制不等于更快,可能增加逃逸、间接访问和共享竞争。接口方法集也受值/指针接收者影响,要验证实际实现和调用方式。
共享指针必须有所有权和同步协议。需要不可变快照时复制结构和底层引用,不能依赖“只是传了一个指针”来获得并发安全。
常见误区
- 误区:复制包含 Mutex 的结构体。改正:同步字段应保持唯一实例,使用指针并明确不可复制约束。
- 误区:指针接收者就一定更快。改正:结合结构大小、逃逸、缓存局部性和 profile 判断。
- 误区:多个 goroutine 共享指针却没有同步。改正:使用锁、原子、消息所有权或不可变副本。