已定义
type MyInt int
我想定义一个只打印值的方法.ShowMe()
。我可以使用*MyInt
:
func (this *MyInt) ShowMe() {
fmt.Print(*this, "\n")
}
或使用MyInt
:
func (this MyInt) ShowMe() {
fmt.Print(this, "\n")
}
在什么情况下建议在值上定义方法而不是指针?
答案 0 :(得分:9)
做出这个决定时,有两个问题要问自己:
如果这两个问题的答案都是肯定的,那么在指针上定义方法。
在您的示例中,您不需要修改接收器的值,并且复制接收器并不昂贵。
为了确定#2的答案,我的经验法则是:如果接收器是具有多个字段的结构,则通过指针传递。否则按值传递。
答案 1 :(得分:5)
Go FAQ(CC-licensed)有一个答案:
Should I define methods on values or pointers?
func (s *MyStruct) pointerMethod() { } // method on pointer func (s MyStruct) valueMethod() { } // method on value
对于不习惯指针的程序员来说,区别 这两个例子可能令人困惑,但事实上情况确实如此 非常简单。在类型上定义方法时,接收器(在 上面的例子)就像它是一个参数一样 方法。是将接收器定义为值还是指针 同样的问题,那么,函数参数是否应该是a 值或指针。有几点需要考虑。
首先,最重要的是,该方法是否需要修改 接收器?如果是,则接收器必须是指针。 (切片和 地图是参考类型,所以他们的故事有点微妙,但是 例如,在接收器的方法中改变切片的长度 必须仍然是一个指针。)在上面的例子中,如果
pointerMethod
修改s的字段,调用者将看到这些更改,但是 调用valueMethod
时带有调用者参数的副本(即 传递值的定义),所以它会做出改变 对来电者不可见。顺便说一句,指针接收器与Java中的情况相同, 虽然在Java中,指针隐藏在封面下;这是Go的 价值接收器是不寻常的。
其次是效率的考虑。如果接收器很大,a 例如,大
struct
,使用指针要便宜得多 接收机。接下来是一致性。如果该类型的某些方法必须具有 指针接收器,其余的也应该是,所以方法集是 无论使用何种类型,都是一致的。见the section on method sets 详情。
对于基本类型,切片和小
structs
等类型,值 接收器非常便宜,所以除非方法的语义要求 一个指针,一个值接收器是高效和清晰的。