为了账号安全,请及时绑定邮箱和手机立即绑定

为什么带有指针接收器的方法在接收值时仍然有效?

为什么带有指针接收器的方法在接收值时仍然有效?

Go
qq_笑_17 2021-06-09 13:28:46
我只是在玩围棋巡回赛中的练习 51。该解释声称该Scale方法在接收 aVertex而不是指向 a 的指针时无效Vertex。然而,当我改变声明v := &Vertex{3, 4},以v := Vertex{3, 4}在main输出唯一的变化是丢失的&标记指针。那么为什么Scale即使变量不是指针也会改变它接收到的变量呢?
查看完整描述

2 回答

?
拉丁的传说

TA贡献1789条经验 获得超8个赞

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

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

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


查看完整回答
反对 回复 2021-06-21
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

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

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

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


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 222 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信