类型之间有什么区别。实现和类型。满足?

What's the difference between types.Implements and types.Satisfies?

提问人:Seiya 提问时间:11/8/2023 最后编辑:Seiya 更新时间:11/9/2023 访问量:82

问:

类型之间有什么区别。实现类型。满足于golang?

我正在编写一个检查Go AST的代码。

Go 类型 标准库

评论

1赞 Volker 11/8/2023
Go 的类型系统有两个关系:“某个类型 T 实现接口 I 的所有方法”的实现和约束满足,即“某个类型 A 是否满足对泛型类型 G 的类型参数 P 施加的约束”。(实际上,您不需要知道,因为您不需要使用包类型)。
0赞 Seiya 11/8/2023
谢谢你的评论。当它们不同时,我想知道更具体的例子。某些 A 型是否可以在不“满足”I 的情况下“实现”接口 I,反之亦然?实际上,我正在研究 Go AST 并将使用包类型。
4赞 JimB 11/8/2023
例如,是一个可以满足的类型约束,但它没有可以实现的方法。constraints.Integer
0赞 Seiya 11/8/2023
非常感谢!然后,键入。实现与方法实现和类型相关。满足与方法实现和类型约束有关,对吧?
2赞 JimB 11/8/2023
它可能只对类型约束有意义,因为文档说“报告类型 V 是否满足约束 T”。我想您的困惑可能是因为“接口”在编译和运行时多态性期间都用于类型约束,但在每个上下文中都有不同的用途。SatisfiesSatisfies

答:

3赞 blackgreen 11/8/2023 #1

tl;博士

一个类型可以“满足”而不“实现”它,即不属于它的类型集。comparable


方法名称与语言规范直接相关,因此首先查看它会有所帮助:

实现定义为:

类型 T 实现接口 I,如果

  • T 不是接口,而是 I 类型集的元素;或
  • T 是一个接口,T 的类型集是 I 类型集的子集。

“类型集”的概念也在规范中定义,这取决于你正在考虑的接口类型。基本接口是那些只包含方法的接口,类型集是实现这些方法的所有类型的集合,例如:

// type set includes all types with the method Read (signature must match)
type Reader interface {
    Read([]byte) (int, error)
} 

非基本接口是那些包含类型术语(以及零个或多个方法)的接口,类型集是指定类型的集合。如果任何术语是近似值,例如 该集包括具有基础类型的类型。~intint

// type set includes int, string and anything with int or string as underlying type
type Foo interface {
    ~int | ~string
}

Satisfying 仅用于接口约束,定义为:

类型 T 满足约束 C,如果满足以下条件

  • T 实现 C;或
  • C 可以写成 interface{ comparable;E },其中 E 是基本接口,T 是可比较的,并实现 E。

如您所见,“满意”的定义包括“实施”和例外。

在 Go 1.20 之前,“满足”接口(任何接口)的概念并不存在。每个用例都被称为“实施”。

在 Go 1.20 中,引入了“satisfying”来扩展“实现约束”的定义,但对于必须满足的类型有一个例外(上面引用中的第二个要点)。以前,尽管在非泛型代码中支持和运算符,但诸如 or 之类的类型没有实现。comparablereflect.Type[2]io.Readercomparable==!=

换言之,规范中可比较的定义与约束的实际类型集之间存在不匹配。comparable

更多信息:Go 泛型:映射键的类型约束?