通过对象而不是指向它的指针调用带有指针接收器的方法?
Posted
技术标签:
【中文标题】通过对象而不是指向它的指针调用带有指针接收器的方法?【英文标题】:Calling a method with a pointer receiver by an object instead of a pointer to it? 【发布时间】:2016-11-23 16:47:30 【问题描述】:v
是Vertex
的对象,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 答案以上是关于通过对象而不是指向它的指针调用带有指针接收器的方法?的主要内容,如果未能解决你的问题,请参考以下文章