我只是在玩Exercise 51 in the Tour of Go . 该解释声称 Scale
方法在收到 Vertex
而不是指向 Vertex
的指针时无效 .
然而,当我在 main
中将声明 v := &Vertex{3, 4}
更改为 v := Vertex{3, 4}
时,输出中唯一的变化是缺少 &
来标记指针 .
那么为什么 Scale
改变它收到的变量,即使变量不是指针?
我只是在玩Exercise 51 in the Tour of Go . 该解释声称 Scale
方法在收到 Vertex
而不是指向 Vertex
的指针时无效 .
然而,当我在 main
中将声明 v := &Vertex{3, 4}
更改为 v := Vertex{3, 4}
时,输出中唯一的变化是缺少 &
来标记指针 .
那么为什么 Scale
改变它收到的变量,即使变量不是指针?
2 回答
游览建议的差异实际上并不是在改变
v := &Vertex{3, 4}
到v:= Vertex{3, 4}
,而是改变两种方法的定义,以便它们可以处理值而不是指针 . 因此,例如,对于Scale
,func (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
.它没有"receive"一个值 . Go是强类型的,所以如果在某处指定了指向T的指针,则指向T(
*T
)的指针是唯一可以作为此类型位置的值发生的选项 ."magic"在编译器中有效"rewrites"您的代码在某些conditions下:
相关:Method sets