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

2

6

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}
}
Ametropia answered 24/2, 2022 at 5:32 Comment(0)
S
12

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.


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.

Slotter answered 24/2, 2022 at 6:44 Comment(0)
R
-1

Is this assumption correct?

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

Runyon answered 24/2, 2022 at 6:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.