“有效的Go”文档说明以下内容。
关于指针与接收器的值的规则是,可以在指针和值上调用值方法,但是只能在指针上调用指针方法。
http://tip.golang.org/doc/effective_go.html#pointers_vs_values
这样,如果我定义如下所示的方法,那么使用值不能调用它吗?
func (self *someStruct) Change(newNum int) { self.propertyOne = newNum }
但是,以下似乎仍然有效。
structInstance := &someStruct{ propertyOne: 41, } (*structInstance).Change(456)
为什么?
是否将值转换(*structInstance)回Change调用的地址/指针?
(*structInstance)
Change
如何确保某个类型的实例不能调用指针上定义的方法(如Change)?
http://play.golang.org/p/azbpp_djlG
根据语言规范:
x.m()如果方法集(的类型)x包含m并且参数列表可以分配给的参数列表,则该方法调用有效m。如果x是可寻址且&x方法集包含m,x.m()则为(&x).m()
x.m()
x
m
&x
(&x).m()
在您的示例中,的方法集中没有Change方法(*structInstance),但是它是可寻址的,并且该方法存在于&(*structInstance)的方法集中,因此该调用被解释为(&(*structInstance)).Change(456)或更简单structInstance.Change(456)。
&(*structInstance)
(&(*structInstance)).Change(456)
structInstance.Change(456)
防止此行为的唯一方法是还要在Change上定义方法someStruct,也许会使它感到恐慌。但是,这不是理想的,因为它只会在运行时告诉您有关问题的信息。构造您的程序将不会造成混乱,因此使用此速记实际上并不重要。
someStruct