Go泛型中为何无法从主类型推断从属类型的泛型参数?
Go泛型中类型参数无法自动推导的原因解析
我在Go中编写了一段泛型代码,其中定义了带有泛型参数的“主类型”A[T],以及多个需要共享同一泛型参数的“从属类型”(如B[T])。代码示例如下:
type Doer[T any] interface { ModifyA(*A[T]) } type B[T any] struct { } func NewB[T any]() *B[T] { return new(B[T]) } func (b *B[T]) ModifyA(a *A[T]) { // Do a thing } type A[T any] struct{} func NewA[T any]() A[T] { return A[T]{} } func (a *A[T]) Run(doers ...Doer[T]) { for _, doer := range doers { doer.ModifyA(a) } } func main() { a := new(A[int]) a.Run(NewB()) // 此处编译错误:cannot infer T }
理论上,当为A指定泛型参数int后,B的泛型参数应该自动设为int,这类代码在其他支持泛型的语言中可以正常运行,但在Go中,上述标注错误的行会出现“cannot infer T”编译错误。虽然可以通过显式调用NewB[int]()解决,但写法过于冗长。
问题原因
Go的泛型类型推导遵循局部性原则,不支持跨上下文的反向推导,具体原因如下:
- Go编译器对泛型函数的类型推导仅局限于当前函数调用的直接上下文:比如泛型函数的参数、或者返回值被直接赋值给明确类型的变量时,编译器才能推导类型参数。而
NewB()是无参数的泛型函数,它的返回值仅作为Run方法的可变参数传入,编译器无法从Run期望的Doer[int]类型反向推导NewB的类型参数T。 - 部分支持泛型的语言(如C#)实现了目标类型推导,即可以根据函数调用的目标场景(比如作为参数传递给需要特定类型的函数)来推导泛型参数,但Go目前并未支持这种推导逻辑,它的推导规则更保守,只关注当前函数调用的输入输出信息,不会向上传递推导需求。
内容的提问来源于stack exchange,提问作者Woody1193
相关产品推荐
相关产品推荐

