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

go, methods, pointers

Solution

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` contains `m` and the argument list can be assigned to the parameter list of `m`. If `x` is addressable and &x's method set contains `m`, `x.m()` is shorthand for `(&x).m()`:

Related: Method sets

Problem

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?

Original source