Go的method set

在学习Go的接口时
在这里插入图片描述
左边的说明中说:

Note: There is an error in the example code on line 22. Vertex (the value type) doesn’t implement Abser because the Abs method is defined only on *Vertex (the pointer type).

意思就是右边的代码22行有错误。Vertex没有实现Abser,因为Abs方法只为指针类型。
运行后也确实报错:

./prog.go:22:4: cannot use v (type Vertex) as type Abser in assignment:
	Vertex does not implement Abser (Abs method has pointer receiver)

首先注释掉第22行,运行正确
接着,把Abs()方法的指针接收器改为值接收器,运行依旧正确

这就很迷惑了:
如果是*Vertex,会同时实现指针接收器和值接收器的方法的接口
如果是Vertex,则只能实现值接收器的方法的接口

这里详细说明了出现这种错误的原因https://stackoverflow.com/a/40824044

我感觉比较重要的一个概念是method sets
method sets的官方解释

A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing embedded fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.
The method set of a type determines the interfaces that the type implements and the methods that can be called using a receiver of that type.

简单来说就是类型会有一个method set,接口类型的method set是它的接口,其他类型T的method set是所有类型T作为接收器的方法,*T的method set包括T或*T作为接收器的方法

所以上面的问题就可以这么解释:
*Vertex类型的method set包括*Vertex和Vertex作为接收器的方法,所以无论接收器的类型是值还是指针,方法都在*Vertex类型的method set中,就可以认为实现了Abser接口
而Vertex类型的method set仅包括Vertex作为接收器的方法,所以当接收器类型变为*Vertex时,该方法不在Vertex类型的method set中,所以编译器认为该类型没有实现Abser接口

Go的interface是实现多态的基础,即如果interface的method set在多个类型中都有完整定义(interface的method set是其他类型method set的子集),则我们可以称这些类型隐式实现了interface,进而就可以使用同一interface类型的变量指代多种类型。这似乎有点像Python中的鸭子类型

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

但没有Python的鸭子类型灵活,这是因为interface的method set必须是其他类型method set的子集

如果不了解这个背景的话,会很难理解a tour of go中这部分内容,所以这篇内容算是补充说明吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值