为了账号安全,请及时绑定邮箱和手机立即绑定

在“A Go Tour”中,如何修改接口以需要指针上的方法?

在“A Go Tour”中,如何修改接口以需要指针上的方法?

Go
Cats萌萌 2021-11-15 20:38:17
在接口的“A Go Tour”中,我们有这个接口:type Abser interface {    Abs() float64}说明这种类型Vertex不满足上述Abser:type Vertex struct {    X, Y float64}func (v *Vertex) Abs() float64 {    return math.Sqrt(v.X*v.X + v.Y*v.Y)}如何修改 Abser 接口以使 Vertex 满足它?(如果它不再满足完整示例中的 MyFloat 也没关系。)在我发布这个问题之前,我花了几个小时搜索和挠头,但发布后我发现了另一个 SO 问题,它涵盖了类似的材料,可能对其他新手有帮助:
查看完整描述

1 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

您对什么正在实施什么感到有些困惑。在这种情况下,*Vertex正在实现Abser而不是Vertex让它也这样Vertex做,您必须更改实现中的接收类型Abs,使其不是指针;


func (v Vertex) Abs() float64 {

    return math.Sqrt(v.X*v.X + v.Y*v.Y)

} // Vertex implementing Abser here

所以你表达这个问题的方式有点误导。接口不需要更改,应该不会收到任何更改。仅供参考,您可以同时拥有*Vertex并Vertex使用我上面提供的方法以及您已经拥有的方法来实现接口。


这是在 Go 中经常绊倒人们的一点。当你声明func (t SomeType)你指定接收类型时,如果这是一个指针,(t *SomeType)那么实现接口的东西不是SomeType而是*SomeType。这与方法由类实现的其他语言略有不同,无论您使用的是引用还是值都没有关系。在 Go 中,该类不实现该方法,您指定“接收类型” - 可以调用该方法的东西 - 第一个参数实际上被压入堆栈并与传递给方法的参数相同,区别仅与编译有关(接口实现确实是具有 afaik 功能的唯一原因)。所以,总而言之,如果你想Vertex实现Abser具有单个方法的接口,Abs() float64那么您需要将该函数定义为func (v Vertex) Abs() float64 { ... }.


只是为了有清晰可读的代码,我建议不要为指针和值定义接口......您可以使用地址或取消引用运算符来解决这个问题。


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信