MENU

[FAQ]为什么类型T不满足Equal接口?

November 7, 2020 • Go FAQ

考虑以下简单的接口,它表示一个可以将自身与另一个值进行比较的对象:

type Equaler interface {
    Equal(Equaler) bool
}

以及此类型 T

type T int
func (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler

不像在一些多态类型系统中类似的情况,T 并未实现 EqualerT.Equal 的实参类型为 T,而非字面上所需要的类型 Equalar

在Go中,类型系统并不提升 Equal 的实参,那是程序员的责任, 就以下类型 T2 所示,它实现了 Equaler

type T2 int
func (t T2) Equal(u Equaler) bool { return t == u.(T2) }  // 满足Equaler

即使它不像其它的类型系统也好,因为在Go中_任何_满足 Equaler 的类型都能作为实参传至 T2.Equal,并在运行时我们必须检查该实参是否为 T2类型。一些语言将其安排在编译时以保证做到这一点。

一个相关的例子是另一种情形:

type Opener interface {
    Open() Reader
}

func (t T3) Open() *os.File

在Go中,T3 并不满足 Opener,尽管它在另一种语言中可能满足。

在相同情况下,Go的类型系统确实为程序员做的更少, 子类型化的缺乏使关于接口满足的规则非常容易制订: 函数的名字和签名完全就是那些接口吗?Go的规则也容易高效地实现。 我们感觉这些效益抵消了自动类型提升的缺失。Go在某天应当采取一些泛型的形式, 我们期望会有一些方式来表达这些例子的想法,且也拥有静态检查。

ArchivesQR Code
QR Code for this page
Tipping QR Code