通过对象而不是指向它的指针调用带有指针接收器的方法?

Posted

技术标签:

【中文标题】通过对象而不是指向它的指针调用带有指针接收器的方法?【英文标题】: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 := Vertex3, 4
    v.Scale(10)
    fmt.Println(v.Abs())

【问题讨论】:

【参考方案1】:

Spec: Calls:

如果x的(类型)method set包含m并且参数列表可以分配给m的参数列表,则方法调用x.m()是有效的。如果x 是addressable 并且&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 答案

以上是关于通过对象而不是指向它的指针调用带有指针接收器的方法?的主要内容,如果未能解决你的问题,请参考以下文章

交换对象数组是不是会影响指向它的指针

c++ 虚函数 如何调父类 而非子类

通过指针C++调用成员函数,对象为空?

没有为指向结构的指针调用 ctypes.Structure 子类的 ctypes __del__

在带有指向堆栈变量的指针的函数调用之间使用传输值(按值?)

018-智能指针