You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言:为何*Vertex类型可调用Abs()?接口实现疑问

为什么*Vertex能调用值接收者的Abs()方法?

嘿,这个问题问到点子上了!这其实是Go语言方法集自动适配的特性在背后起作用,咱们结合你的代码一步步理清楚:

首先看你的方法定义:

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

这里Abs()的接收者是值类型Vertex,不是指针类型*Vertex。那为什么a(类型是*Vertex)能调用它呢?

Go的方法集规则:指针自动解引用

Go语言有个很贴心的设计:当你使用指针类型的变量调用方法时,编译器会自动帮你做指针解引用。也就是说,当你写a.Abs()的时候,Go会偷偷把它转换成:

(*a).Abs()

而*a就是一个Vertex值,正好匹配Abs()的值接收者,所以方法能正常执行。

关于接口实现的补充

你提到“*Vertex并未实现Abs()方法”,其实从接口实现的角度来说,*Vertex是完全满足Abser接口的。因为Go里:

  • 值类型T的方法集只包含接收者为T的方法
  • 指针类型*T的方法集同时包含接收者为T和*T的方法

所以*Vertex的方法集里自然包含了Abs(),也就实现了Abser接口,这也是为什么你能把&v赋值给a(Abser类型变量)的原因。

反过来,如果Abs()是指针接收者,那值类型Vertex能不能调用它?其实也可以,Go会自动取地址(相当于(&v).Abs()),但如果是不可寻址的值(比如字面量Vertex{1,2})就不行啦。

内容的提问来源于stack exchange,提问作者Pei Hsiang Hung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:48:03