选择标准主要有三条:是否需要修改接收者状态(需要则用指针);类型的大小与拷贝成本(大结构体用指针);类型是否天然不可变或很小(如 time.Time、小坐标点用值)。此外并发共享的对象必须用指针并自己保证同步。
关键规则是方法集:类型 T 的方法集只含值接收者方法,*T 的方法集包含两者。这决定了接口满足关系——把 T 值赋给接口时,指针接收者实现的方法不可用。一致性原则:一个类型的所有方法应统一风格,一旦某个方法用了指针接收者,其余通常都用指针,避免使用方困惑。
type Counter struct{ n int }
func (c *Counter) Inc() { c.n++ } // 修改状态,必须指针
func (c Counter) Value() int { return c.n } // 只读可用值,但建议与 Inc 统一为指针
易错点:对值接收者的修改只作用于副本,是无声的 bug;map 元素不可取地址,不能对其调用指针接收者方法,需先取出再操作。追问方向:方法表达式与方法值、嵌入类型方法集的提升规则。