问题
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())
}
回答1:
Spec: Calls:
A method call
x.m()is valid if the method set of (the type of)xcontainsmand the argument list can be assigned to the parameter list ofm. Ifxis 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.
回答2:
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.
来源:https://stackoverflow.com/questions/38481420/calling-a-method-with-a-pointer-receiver-by-an-object-instead-of-a-pointer-to-it