最佳答案
对于我来说,在哪种情况下我想使用值接收器而不是总是使用指针接收器是非常不清楚的。
从文件中总结一下:
type T struct {
a int
}
func (tv T) Mv(a int) int { return 0 } // value receiver
func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver
文档还说:“对于基本类型、切片和小结构等类型,值接收器非常便宜,所以除非方法的语义需要指针,否则值接收器是有效和清晰的。”
第一点他们说值接收器“非常便宜”,但问题是它是否比指针接收器便宜。所以我做了一个小的基准测试(要点代码),它告诉我,即使对于只有一个字符串字段的结构体,指针接收器也更快。结果如下:
// Struct one empty string property
BenchmarkChangePointerReceiver 2000000000 0.36 ns/op
BenchmarkChangeItValueReceiver 500000000 3.62 ns/op
// Struct one zero int property
BenchmarkChangePointerReceiver 2000000000 0.36 ns/op
BenchmarkChangeItValueReceiver 2000000000 0.36 ns/op
(编辑:请注意,第二点在新的go版本中无效,见评论。)
第二点文档说一个有价值的接收者是“高效和清晰”的;这更像是品味的问题,不是吗?就我个人而言,我更喜欢在所有地方使用相同的东西。什么意义上的效率?性能方面,指针似乎总是更有效。很少使用一个int属性的测试运行显示值接收器的最小优势(范围为0.01-0.1 ns/op)
谁能告诉我一个例子,一个值接收器明显比一个指针接收器更有意义?还是我在基准测试中做错了什么?我是否忽略了其他因素?