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]andBox[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. ParsingName()is fragile, so avoid relying on it.
More on Generics
- Q143Are generic types covariant? Can a
Box[Dog]be used as aBox[Animal], or aBox[int]converted to aBox[MyInt]? - Q144What is an "instantiation cycle"? Why does this recursive generic function fail to compile?
- Q146Write a generic fan-in
Mergefor channels. What are the concurrency pitfalls? - Q147How do you get a pointer to a literal value generically? Compare a
Ptr[T]helper with Go 1.26new(expr).