指针上定义的方法仍然可以用值调用 [英] Method defined on pointer still callable with value
问题描述
有效执行"文档中的内容如下.
The "Effective Go" documentation says the following.
关于接收器的指针与值的规则是,可以在指针和值上调用值方法,但是只能在指针上调用指针方法.
The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers.
http://tip.golang.org/doc/effective_go.html#pointers_vs_values
这样,如果我定义如下方法,不是可以用值调用它吗?
As such, if I define a method like the following, wouldn't it not be callable with a value?
func (self *someStruct) Change(newNum int) {
self.propertyOne = newNum
}
但是,以下似乎仍然有效.
However, the following still seems to work.
structInstance := &someStruct{
propertyOne: 41,
}
(*structInstance).Change(456)
为什么?
是否将值(* structInstance)
转换回用于 Change
调用的地址/指针?
Is it converting the value (*structInstance)
back into an address/pointer for the Change
call?
如何确保类型的某些实例不能调用指针上定义的方法(如 Change
)?
How do I ensure that some instance of a type cannot call a method defined on the pointer (like Change
)?
http://play.golang.org/p/azbpp_djlG
推荐答案
来自语言规范:
如果
x
的方法集包含m
并且参数列表可以,则方法调用xm()
是有效的分配给m
的参数列表.如果x
是可寻址的,并且& x
的方法集包含m
,则xm()
是(& x).m()
A method call
x.m()
is valid if the method set of (the type of)x
containsm
and the argument list can be assigned to the parameter list ofm
. Ifx
is addressable and&x
's method set containsm
,x.m()
is shorthand for(&x).m()
在您的示例中,(* structInstance)
的方法集中没有 Change
方法,但是它是可寻址的,并且该方法存在于&中.(* structInstance)
的方法集,因此该调用将被解释为(&(** structInstance)).Change(456)
,或更简单地说是 structInstance.Change(456)
.
In your example, there is no Change
method in (*structInstance)
's method set, but it is addressable and the method exists in &(*structInstance)
's method set, so the call is interpreted as (&(*structInstance)).Change(456)
, or more simply structInstance.Change(456)
.
防止这种行为的唯一方法是还要在 someStruct
上定义 Change
方法,也许会使它感到恐慌.但是,这不是理想的,因为它只会在运行时告诉您有关该问题的信息.构造您的程序将不会造成混乱,因此使用此速记实际上并不重要.
The only way to prevent this behaviour would be to also define the Change
method on someStruct
, perhaps making it panic. That's not ideal though, since it will only tell you about the problem at runtime. It would be less confusing to structure your program so that the use of this shorthand doesn't actually matter.
这篇关于指针上定义的方法仍然可以用值调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!