Name the restrictions around type parameters: embedding, type declarations, and method sets.
Question 126HardGo 1.22 to 1.25
The main restrictions, several of which exist to keep method sets statically known:
- No embedding a type parameter:
type Wrapper[T any] struct{ T }fails with "embedded field type cannot be a (pointer to a) type parameter". The promoted method set would depend on T. - No type parameter as a declaration's RHS:
type Box[T any] Tfails with "cannot use a type parameter as RHS in type declaration". - No methods on T: you can only declare methods on the generic type (
Box[T]). - No generic closures or generic methods (see previous questions).
- Uninstantiated generic types are not types:
var s Stackfails. You must writeStack[int]. - Type assertion to a generic type must be instantiated:
x.(Stack[int]). - A generic type may refer to itself inside its own definition, but not in a way that expands forever.
type Node[T any] struct{ next *Node[T] }and even*Node[int]are fine.*Node[[]T]is rejected with "instantiation cycle", becauseNode[int]would needNode[[]int], which needsNode[[][]int], and so on.
// Use a named field instead of embedding
type Wrapper[T any] struct {
Val T
}
func (w Wrapper[T]) Get() T { return w.Val }
Mentioning the infinite-instantiation rule is what separates a senior answer from a mid-level one.
More on Generics
- Q124Why doesn't Go allow type parameters on methods? What do you do instead?
- Q125How do you write methods on a generic type? What is wrong with
func (s Stack[int]) Sum() int? - Q127Explain the "pointer method" constraint pattern (
PT interface{ *T; M() }). Why is it needed? - Q128What are self-referential (recursive) constraints and generic interfaces? Give an example.
- Q129Why does
slices.Clonehave the signaturefunc Clone[S ~[]E, E any](s S) Sinstead offunc Clone[E any](s []E) []E? - Q130How does the Go compiler implement generics (GC shape stenciling with dictionaries)? What are the performance implications?