9 go
定义了
type MyInt int
Run Code Online (Sandbox Code Playgroud)
我想定义一个.ShowMe()只打印值的方法.我可以使用*MyInt以下方法定义:
func (this *MyInt) ShowMe() {
fmt.Print(*this, "\n")
}
Run Code Online (Sandbox Code Playgroud)
或使用MyInt:
func (this MyInt) ShowMe() {
fmt.Print(this, "\n")
}
Run Code Online (Sandbox Code Playgroud)
在什么情况下建议定义值的方法,而不是指针?
做出这个决定时,有两个问题要问自己:
如果这些问题中的任何一个的答案都是肯定的,那么在指针上定义方法.
在您的示例中,您不需要修改接收器的值,并且复制接收器并不昂贵.
为了确定#2的答案,我的经验法则是:如果接收器是具有多个字段的结构,则通过指针传递.否则按值传递.
小智 5
我应该在值或指针上定义方法吗?
Run Code Online (Sandbox Code Playgroud)func (s *MyStruct) pointerMethod() { } // method on pointer func (s MyStruct) valueMethod() { } // method on value对于不习惯指针的程序员来说,这两个例子之间的区别可能令人困惑,但实际情况非常简单.在类型上定义方法时,接收器(上例中的s)的行为就像它是方法的参数一样.然后,将函数参数定义为值还是指针,将接收器定义为值还是指针都是同一个问题.有几个注意事项.
首先,最重要的是,该方法是否需要修改接收器?如果是,接收器必须是指针.(切片和贴图是引用类型,因此它们的故事更加微妙,但是例如在方法中更改切片的长度,接收器必须仍然是指针.)在上面的示例中,如果
pointerMethod修改s的字段,调用者将看到这些更改,但是valueMethod使用调用者参数的副本调用(这是传递值的定义),因此调用者所做的更改将对调用者不可见.顺便说一句,指针接收器与Java中的情况相同,尽管在Java中,指针隐藏在封面下; Go的价值接收器是不寻常的.
其次是效率的考虑.如果接收器很大,
struct例如,使用指针接收器便宜得多.接下来是一致性.如果该类型的某些方法必须具有指针接收器,则其余方法也应如此,因此无论使用何种类型,方法集都是一致的.有关 详细信息,请参阅方法集部分.
对于诸如基本类型,切片和小类型之类的类型,
structs值接收器非常便宜,因此除非方法的语义需要指针,否则值接收器是高效且清晰的.