Go

What does this print? (%T and reflection on generic types)

Question 145HardGo 1.22 to 1.25
type Pair[K comparable, V any] struct {
    Key K
    Val V
}
type Box[T any] struct{ v T }
type MyInt int

func main() {
    fmt.Printf("%T\n", Pair[string, int]{})
    fmt.Printf("%T\n", Box[MyInt]{})
    fmt.Println(reflect.TypeOf(Box[[]string]{}).Name())
    fmt.Println(reflect.TypeOf(Box[int]{}) == reflect.TypeOf(Box[MyInt]{}))
}

Output:

main.Pair[string,int]
main.Box[main.MyInt]
Box[[]string]
false
  • At run time each instantiation is a fully concrete type. Its name includes the type arguments, package-qualified and separated by commas without spaces.
  • reflect.Type.Name() omits the package path but keeps the arguments.
  • Box[int] and Box[MyInt] share a GC shape and may share compiled code, but they are distinct types to reflection, type switches and == on interfaces. GC shape stenciling is an implementation detail and is never visible to the program.
  • There is no reflection API to get "the generic type Box" or to instantiate a generic type at run time. Parsing Name() is fragile, so avoid relying on it.

More on Generics

All 36 Generics questions