“Effective 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
来电的地址/指针?
如何确保某个类型的实例无法调用指针上定义的方法(如Change
)?
答案 0 :(得分:2)
当在指针接收器上定义函数时,Go会自动将值转换为该函数的指针。
type Cookies struct {
Num int
}
func (c *Cookies) Buy(n int) {
c.Num += n
}
func main() {
c := Cookies{}
c.Buy(10) //is equal to (&c).Buy(10)
fmt.Println(c)
}
我无法找到现在定义的位置的引用,但我知道它在规范中的某个官方文档中。
另外请注意,请不要在Go中使用self
或this
。
//修改
来自http://tip.golang.org/ref/spec#Calls:
如果方法集x(类型)x包含m并且参数列表可以分配给m的参数列表,则方法调用x.m()有效。 如果x是可寻址的且& x的方法集包含m,则x.m()是(& x).m()
的缩写
答案 1 :(得分:1)
如果方法集{(1)}的
的简写x.m()
包含x
并且参数列表可以分配给{{1}的参数列表,则方法调用m
有效}。如果m
可寻址且x
的方法集包含&x
,则m
是x.m()
在您的示例中,(&x).m()
的方法集中没有Change
方法,但它是可寻址的,并且该方法存在于(*structInstance)
的方法集中,因此调用是解释为&(*structInstance)
,或更简单地(&(*structInstance)).Change(456)
。
防止此行为的唯一方法是在structInstance.Change(456)
上定义Change
方法,也许会让人感到恐慌。但这并不理想,因为它只会告诉你运行时的问题。构建程序不那么令人困惑,因此使用这种速记实际上并不重要。