9. Generics (Go 1.18+)
Type parameters for reusable algorithms and containers; constrain with any
, comparable
, or ordered sets.
Question: How do you write a generic function in Go?
Answer: You write a generic function by defining type parameters in square brackets after the function name. These type parameters can then be used in the function's parameter list and body. Constraints can be applied to the type parameters to specify what kinds of types are allowed.
Explanation: The most common constraint is any
, which allows any type. The comparable
constraint allows types that can be compared with ==
and !=
. For ordered comparisons, prefer cmp.Ordered
from the standard library (Go 1.21+). Alternatively, import golang.org/x/exp/constraints
or define a custom constraint.
// A generic function to find the minimum of two values (Go 1.21+).
// T is constrained by cmp.Ordered.
func Min[T cmp.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
Question: How do you define a generic type?
Answer: Add type parameters to a type, e.g., a stack or set.
type Stack[T any] struct{ data []T }
func (s *Stack[T]) Push(v T) { s.data = append(s.data, v) }
func (s *Stack[T]) Pop() (T, bool) {
if len(s.data) == 0 { var z T; return z, false }
v := s.data[len(s.data)-1]
s.data = s.data[:len(s.data)-1]
return v, true
}
Question: What are type sets and underlying type constraints?
Answer: Constraints can specify permitted underlying types using ~
. Useful to write functions over custom numeric types.
type Number interface{ ~int | ~int64 | ~float64 }
func Sum[T Number](xs []T) T { var s T; for _, v := range xs { s += v }; return s }
Question: When do you need the
comparable
constraint?
Answer: When using ==
/!=
or as map keys/map[T]U
, constrain T
to comparable
.
Explanation: Only comparable types can be used with equality operators and as map keys.
Question: Do callers have to specify type arguments explicitly?
Answer: Often no; the compiler infers them from arguments/returns. Specify explicitly when inference fails.