Calling a method with a pointer receiver by an object instead of a pointer to it?
v
is an object of Vertex
, and Scale
is a method for a pointer to Vertex
. Then why is v.Scale(10)
not wrong, given that v
isn't a pointer to a Vertex
object? Thanks.
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
v.Scale(10)
fmt.Println(v.Abs())
}
Spec: Calls:
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()
.
The compiler sees that Scale()
has a pointer receiver and also that v
is addressable (as it is a local variable), so v.Scale(10)
will be interpreted as (&v).Scale(10)
.
This is just one of the many conveniences the spec offers you so the source code can remain clean.
It's the Go automatic dereferencing:
From https://golang.org/ref/spec#Method_values:
As with selectors, a reference to a non-interface method with a value receiver using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv.