我可以使用不同的类型参数构建一个泛型类型的切片吗?

huangapple go评论81阅读模式
英文:

Can I construct a slice of a generic type with different type parameters?

问题

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

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}
}
英文:

In the following code I have a token type that contains a literal value. By using an empty interface I can create a slice of tokens and append tokens that have different types. I don't think it's possible to accomplish the same using generics since we wouldn't be able to infer a type for the Slice of tokens. Is this assumption correct?

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}
}

答案1

得分: 9

给定一个参数化的Token类型如下:

type Token[T any] struct {
    TokenType string
    Literal   T
}

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

换句话说,Token[string]不能赋值给Token[int]。也不能赋值给Token[any],因为这里的any被用作静态类型来实例化T

因此,当你用特定的Token[T any]实例构造一个切片时,不同的实例就不能赋值给其元素类型:

tokS := []*Token[string]{tok1, tok2}
// 无效:无法将tok2(类型为*Token[int]的变量)用作数组或切片字面量中类型为*Token[string]的类型

唯一能够容纳不同类型(如Token[string]Token[int])的切片是[]interface{}[]any


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

几乎正确。更准确地说,Token切片不会推断任何东西,因为你必须自己使用具体的泛型类型参数来构造它。

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

英文:

No.

Given a parametrized Token type as:

type Token[T any] struct {
    TokenType string
    Literal   T
}

each instantiation with a different type argument produces a different (named) type.

In other words, Token[string] is not assignable to Token[int]. Nor is it assignable to Token[any] as any here is used as a static type to instantiate T.

So when you construct a slice with a specific instance of Token[T any], different instances are simply not assignable to its element type:

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

The only slice that can hold different types, as Token[string] and Token[int] is []interface{} or []any.

<hr>

> since we wouldn't be able to infer a type for the Slice of tokens. Is this assumption correct?

Almost. More precisely, the slice of Token wouldn't infer anything because you yourself must construct it with a concrete instantiation of the generic type

Type inference is used to deduce missing type parameters from those already supplied for function arguments. Generic types must be explicitly instantiated, with a concrete type argument for each type parameter.

答案2

得分: -1

这个假设是正确的。你可以使用Token[string]Token[int]的切片。

英文:

> Is this assumption correct?

Yes. Your can have a slice of Token[string] or Token[int].

huangapple
  • 本文由 发表于 2022年2月24日 13:32:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/71247543.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定