A type constraint limits which types can replace a Go type parameter. It also determines which operations generic code may perform on values of that parameter. Choose a constraint from what the implementation needs, rather than from every type a caller might pass. section 6.5.2 section 6.1.4
Common choices express different requirements:
- `any` permits any type. `Filter[T any]` can pass each element to a `func(T) bool` and return a `[]T` without requiring an operation on `T` itself. section 6.1.4
- `comparable` permits equality comparisons. It suits a linked list that compares elements or a map whose keys must be comparable; map values can remain `any`. section 6.1 section 6.4
- A custom interface can specify a type set. `int | float32` admits those exact types; adding `~` to a type term also admits defined types with that underlying type. section 6.1.2 section 6.8
type Numeric interface {
~int | ~float64 | ~int64
}
func AddAll[T Numeric](a, b T) T {
return a + b
}
`AddAll` uses a `Numeric` constraint so `a + b` is valid for its type parameter. Without a constraint permitting addition, that expression fails at compile time. section 6.5.2
Constraints also shape generic interfaces. In `Map[K comparable, V any]`, the key and value have independent requirements that flow through the interface and its `HashMap` implementation. When an interface supplies the constraint, code using its type parameter can call only methods in that interface’s method set—not every method a particular argument type happens to have. section 6.4 section 6.5.3
Keep constraints as narrow as the needed operations justify, but benchmark before treating a generic abstraction as a performance problem. Avoid unnecessary interface conversions in hot loops; allocations and escaping values may matter more than a small difference in CPU time. section 6.5.1





