1 回答
TA贡献2011条经验 获得超2个赞
预先声明comparable
的约束是映射键的正确的包罗万象的约束,因为它是由支持==
和!=
(用作映射键的条件)但不是接口1的类型实现的。
这在这里提到:https ://go.dev/ref/spec#Type_constraints
预先声明的接口类型可比较表示所有可比较的非接口类型的集合。具体来说,类型 T 实现可比性,如果:
T
不是接口类型,T
支持操作==
和!=
2
T
是一个接口类型,每个类型在T
的类型集中实现comparable
即使可以比较不是类型参数的接口(可能导致运行时恐慌),它们也不会实现可比较。
这是一个重要的陷阱,因为基本接口类型通常支持相等运算符——比较的是它们的动态类型/值。
因此,您的接口List[X]
可以直接用作映射键,如中所示map[List[int]]string{}
,但它不会实现comparable
,因为它具有无限类型集(它没有术语,因此任何类型都可以实现它)。也Cons
没有实现它,因为它有一个 type 字段List[X]
。对此没有“较弱”的约束。
考虑到嵌入comparable
的约束对映射键也有效,所以如果你真的需要isList()
函数体中的方法,你可以定义一个这样的约束,并让你的列表是映射键结构实现它,而不是声明一个接口字段:
// may use this as a constraint
type List interface {
comparable
isList() bool
}
1:规范中的引述暗示存在实现的接口类型comparable
,但实际上根本不可能comparable
用任何接口实例化:只有方法的接口具有无限类型集,并且具有类型术语的接口不能在任何地方使用,除了作为约束。
2:这个规则其实不包括支持的非接口类型==
,比如type S struct { data any }
,但是这些类型仍然不能实例化comparable
https://go.dev/play/p/N-pmE0XC-hB。这是规范中的错误。
- 1 回答
- 0 关注
- 89 浏览
添加回答
举报