我试图了解 Go 泛型(v1.18)中类型联合约束的用法。这是我尝试过的代码:
type A struct {
}
type B struct {
}
type AB interface {
*A | *B
}
func (a *A) some() bool {
return true
}
func (b *B) some() bool {
return false
}
func some[T AB](x T) bool {
return x.some() // <- error
}
编译器抱怨:
x.some
未定义(类型T
没有字段或方法一些)
这是为什么?如果我不能使用类型的共享方法*A
and *B
,定义类型联合有什么意义*A | *B
at all?
(显然,我可以使用共享方法定义一个接口并直接使用它。但在我的特定用例中,我想明确限制为某些类型。)
将方法添加到接口约束中,而不放弃泛型:
type AB interface {
*A | *B
some() bool
}
func some[T AB](x T) bool {
return x.some() // works
}
这限制了T
到类型*A
or *B
并声明some() bool
method.
然而,正如您已经发现的,这是一种解决方法。你是对的,它应该单独与类型联合一起使用。这是 Go 1.18 的限制。令人困惑的部分是语言规范似乎仍然支持你的理论(方法集 https://tip.golang.org/ref/spec#Method_sets):
接口类型的方法集是接口类型集中每个类型的方法集的交集(结果方法集通常只是接口中声明的方法集)。
此限制似乎仅记录在Go 1.18 发行说明 https://tip.golang.org/doc/go1.18:
当前的泛型实现具有以下限制:
[...]
Go编译器目前只支持调用方法m
在一个值上x
of 类型 参数类型P
if m
明确声明为P
的约束接口。 [...] 虽然m
可能在方法集中P
由于所有类型都在P
实施m
。我们希望在 Go 1.19 中取消这个限制。
Go跟踪器中的相关问题是#51183 https://github.com/golang/go/issues/51183, with 格里塞默的确认 https://github.com/golang/go/issues/51183#issuecomment-1049181719以及决定保留语言规范并记录限制。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)