我可以构造具有不同类型参数的泛型类型切片吗?

pac*_*una 7 generics go slice type-parameter

在下面的代码中,我有一个包含文字值的标记类型。通过使用空接口,我可以创建一个令牌切片并附加具有不同类型的令牌。我认为使用泛型不可能完成相同的任务,因为我们无法推断令牌切片的类型。这个假设正确吗?

type Token struct {
    TokenType string
    Literal interface{}
}

func main(){
    tok1 := &Token{TokenType: "string", Literal: "foo"}
    tok2 := &Token{TokenType: "integer", Literal: 10}
    tokS := []*Token{tok1, tok2}
}
Run Code Online (Sandbox Code Playgroud)

bla*_*een 11

不。

给定参数化Token类型为:

type Token[T any] struct {
    TokenType string
    Literal   T
}
Run Code Online (Sandbox Code Playgroud)

每个具有不同类型参数的实例化都会产生不同的(命名)类型。

换句话说,Token[string] 不可分配给Token[int]。它也不能分配给,Token[any]因为any这里用作实例化的静态类型T

因此,当您使用 的特定实例构造切片时Token[T any],不同的实例根本无法分配给其元素类型:

tokS := []*Token[string]{tok1, tok2}
// invalid: cannot use tok2 (variable of type *Token[int]) as type *Token[string] in array or slice literal
Run Code Online (Sandbox Code Playgroud)

唯一可以容纳不同类型的切片,如Token[string]Token[int][]interface{}or []any


因为我们无法推断令牌切片的类型。这个假设正确吗?

几乎。更准确地说,Token 切片不会推断任何内容,因为您自己必须使用泛型类型的具体实例来构造它

类型推断用于从已为函数参数提供的类型参数中推断出缺失的类型参数。泛型类型必须显式实例化,每个类型参数都有一个具体的类型参数。