Go

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] T fails 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 Stack fails. You must write Stack[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", because Node[int] would need Node[[]int], which needs Node[[][]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

All 36 Generics questions