Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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())
}
like image 266
Tim Avatar asked Jul 20 '16 12:07

Tim


2 Answers

Spec: Calls:

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().

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.

like image 104
icza Avatar answered Oct 23 '22 08:10

icza


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.

like image 32
nessuno Avatar answered Oct 23 '22 07:10

nessuno