Calling a method with a pointer receiver by an object instead of a pointer to it?

心已入冬 提交于 2019-12-17 09:54:19

问题


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




回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!