patterngoTip
Generics basics: type parameters and constraints
Viewed 0 times
Go 1.18+
genericstype parametersconstraintsgo 1.18comparableconstraints.Orderedcmp.Ordered
Error Messages
Problem
Before Go 1.18, writing a function that works on multiple numeric types required duplicating code or using interface{} with runtime type assertions, losing type safety.
Solution
Use type parameters with constraints:
Built-in constraints:
import "golang.org/x/exp/constraints"
// Generic function with type constraint
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
fmt.Println(Min(3, 5)) // int
fmt.Println(Min(3.14, 2.7)) // float64
fmt.Println(Min("b", "a")) // string
// Generic type
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(item T) { s.items = append(s.items, item) }
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
top := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return top, true
}Built-in constraints:
any, comparable. Standard library adds cmp.Ordered in Go 1.21.Why
Type parameters allow writing code once that works with multiple types while preserving compile-time type safety. The constraint specifies which operations are valid on the type parameter.
Gotchas
- Type inference works for function calls but not for type instantiation — Stack[int]{} not Stack{}
- Methods on generic types cannot have additional type parameters beyond what the type declares
- Union constraints (~int | ~float64) allow any type whose underlying type matches — be careful with interface constraints that include methods
Revisions (0)
No revisions yet.