【问题标题】:Calling a method with a pointer receiver by an object instead of a pointer to it?通过对象而不是指向它的指针调用带有指针接收器的方法?
【发布时间】:2016-11-23 16:47:30
【问题描述】:

vVertex 的对象,Scale 是指向Vertex 的指针的方法。那么为什么v.Scale(10) 没有错,因为v 不是指向Vertex 对象的指针?谢谢。

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

【问题讨论】:

    标签: function pointers go methods call


    【解决方案1】:

    Spec: Calls:

    如果x的(类型)method set包含m并且参数列表可以分配给m的参数列表,则方法调用x.m()是有效的。如果xaddressable 并且&x 的方法集包含m,则x.m()(&x).m() 的简写

    编译器看到Scale() 有一个指针接收器,而且v 是可寻址的(因为它是一个局部变量),所以v.Scale(10) 将被解释为(&v).Scale(10)

    这只是规范为您提供的众多便利之一,因此源代码可以保持干净。

    【讨论】:

      【解决方案2】:

      这是 Go 的自动解引用:

      来自https://golang.org/ref/spec#Method_values

      与选择器一样,使用指针对具有值接收器的非接口方法的引用将自动取消对该指针的引用:pt.Mv 等价于 (*pt).Mv。

      【讨论】:

      • 其实这不是一个方法值而是一个简单的方法调用,所以Spec: Calls部分是相关的。
      • 但在我的示例中正好相反。在v.Scale(10) 中,v 不是指针,Scale 需要一个指针接收器。
      • 蒂姆,真的。请参阅相关部分的@icza 答案
      猜你喜欢
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2023-02-09
      • 1970-01-01
      相关资源
      最近更新 更多