繁体   English   中英

为什么带有指针接收器的方法在接收值时仍然可以工作?

[英]Why does a method with a pointer receiver still work when it receives a value?

我只是在环游世界中练习51练习 解释声称Scale方法在接收到Vertex而不是指向Vertex的指针时无效。

然而,当我改变声明v := &Vertex{3, 4}v := Vertex{3, 4}main输出唯一的变化是缺失&来标记指针。

那么,即使变量不是指针,为什么Scale也会更改它收到的变量?

它不会“接收”值。 Go是强类型的,因此,如果在某处指定了指向T的指针,则指向T( *T )的指针是唯一可以作为该类型位置的值出现的选项。

在编译器中,“魔术”可以在某些条件下有效地“重写”您的代码:

如果x的方法集包含m并且可以将参数列表分配给m的参数列表,则方法调用xm()是有效的。 如果x是可寻址的并且&x的方法集包含m ,则xm()(&x).m()简写:

相关: 方法集

游览建议的区别实际上不是将v := &Vertex{3, 4}更改为v:= Vertex{3, 4} ,而是更改了这两种方法的定义,以便它们使用值而不是值指针。 因此,例如,对于Scalefunc (v *Vertex) Scale(f float64) {...变为func (v Vertex) Scale(f float64) {... (请注意(v *Vertex) ,一个指针值,变为(v Vertex) ,一个非指针值)。 在这两种情况下,都应将v的声明保留为v := &Vertex{3, 4}

您会注意到,在第一种情况下,当方法使用指针时,输出为&{15 20} 25 但是,当方法采用值而不是指针时,输出为&{3 4} 5

在这两种情况下, v都是指向Vertex对象的指针。 在第一种情况下,将指针传递给方法,并且一切都按预期工作-对Vertex对象所做的任何修改都将对原始值进行,因此这些更改在方法返回后仍然存在。 在第二种情况下,尽管v仍然是指针,但是Go编译器足够聪明,可以将v.Scale(5)转换为(*v).Scale(5) ,其中v被取消引用,并将结果值传递给Scale

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM