func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
对于不习惯使用指针的程序员,这两个例子之间的区别可能会让人感到困惑,但实际上情况非常简单。当在一个类型上定义一个方法时,接收器(在上面的例子中是s)的行为就像它是方法的一个参数一样。 将接收器定义为值还是指针是一个同样的问题,就像函数参数应该是值还是指针一样。 有几个需要注意的:
首先,也是最重要的一点,该方法是否需要修改接收器? 如果需要,接收器必须是一个指针。(Slices and maps 用作参考,因此它们的故事有些微妙,但是例如,要更改方法中切片Slices的长度,接收者必须仍然是指针。)在上面的示例中,如果pointerMethod修改了 s,调用者将看到这些更改,但是使用调用者参数的副本(即传递值的定义)来调用valueMethod,因此,所做的更改对于调用者而言是不可见的。
顺便说一下,在Java中,方法接收器总是指针,虽然其指针的性质有些被掩盖了(有人提议在语言中增加值接收器)。Go中的值接受器才是与众不同的。
其次是对效率的考虑。如果接收器很大,比如一个大的结构,使用指针接收器会高效很多。
其次是一致性。如果类型的某些方法必须有指针接收器,那么其余的方法也应该有指针接收器,所以无论类型如何使用,方法集都是一致的。详见method sets一节。
对于基本类型、切片、小结构等类型,值接收器是非常方便的,所以除非方法的语义需要指针,否则值接收器就已经高效而清晰的。
GOlang 好文推荐golang.org/doc/faq#ass…