liveBook · Manning

Type constraint

As explained in Go in Action, Second Edition

A type constraint restricts the types that may be substituted for a type parameter and specifies operations guaranteed to be valid for those types.

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

How Go in Action, Second Edition covers it

How deep it goes
Works through built-in constraints, custom type sets, underlying-type matching, multiple parameters, compiler errors, and performance considerations.
Examples
Uses recipe filtering, numeric addition, linked lists, and a map with separately constrained keys and values.
What it assumes
Assumes familiarity with Go slices, functions, and interfaces while introducing type parameters through filtering and collection implementations.
What you can do after
Build it from scratch: choose constraints for type-safe Go functions and collections, then check operator requirements and benchmark when needed.
How it connects
Connects type parameters with interfaces, method sets, generic collections, type inference, and compile-time type safety.

Also explained in

Compare how 6 books explain type constraint →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Action, Second Edition. The section links point to the parts of the book it draws on.