I was just playing with Exercise 51 in the Tour of Go. The explanation claims the Scale
method has no effect when it receives a Vertex
instead of a pointer to a Vertex
.
Yet when I change the declaration v := &Vertex{3, 4}
to v := Vertex{3, 4}
in main
the only change in the output is the missing &
to mark the pointer.
So why does Scale
change the variable it receives even if the variable isn't a pointer?
It does not "receive" a value. Go is strongly typed, so if somewhere a pointer to T is prescribed, a pointer to T (*T
) is the only option which can happen as a value for such typed place.
The "magic" is in the compiler which effectively "rewrites" your code under certain conditions:
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()
:
Related: Method sets
The difference that the tour suggests isn't actually in changing v := &Vertex{3, 4}
to v:= Vertex{3, 4}
, but rather in changing the definitions of the two methods so that they work on values instead of pointers. So, for example, for Scale
, func (v *Vertex) Scale(f float64) {...
becomes func (v Vertex) Scale(f float64) {...
(note that (v *Vertex)
, a pointer value, becomes (v Vertex)
, a non-pointer value). In both cases, you should leave the declaration of v
as v := &Vertex{3, 4}
.
You'll notice that in the first case, when the methods take pointers, the output is &{15 20} 25
. However, when the methods take values rather than pointers, the output is &{3 4} 5
.
In both cases, v
is a pointer to a Vertex
object. In the first case, the pointer is passed to the methods, and everything works as expected - any modifications made to the Vertex
object are made to the original value, so those changes persist after the method returns. In the second case, though v
is still a pointer, the Go compiler is smart enough to convert v.Scale(5)
to (*v).Scale(5)
, where v
is dereferenced, and the resulting value is passed to Scale
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With