I don’t have a lot to expand on in this section, except to offer a pre-amble about some technical terms and symbols that won’t be familiar to everyone:
≡
is a symbol from mathematics that means “identical to”. It’s similar to=
which we’re all famliar with, but “stricter”. The spec uses variants of this symbol in some following equations, so it’s nice to understand what the symbol means originally.≡
A
means “are assignable to each other”, as in:X ≡
A
Y
means “X is assignable to Y and Y is assignable to X”≡
C
means “satisifes constraint”, as in:X ≡
C
~int
means “X satisfies constraint~int
”.- LHS & RHS stand for Left-Hand Side and Right-Hand Side, and refer to the different halves of an equation. In the equation
x = y + 3
, the Left-Hand Side (LHS) isx
and the Right-Hand Side (RHS) isy + 3
So with that down, let’s read through what the spec has to say about type equations
Type inference
…
Each such pair of matched types corresponds to a type equation containing one or multiple type parameters, from one or possibly multiple generic functions. Inferring the missing type arguments means solving the resulting set of type equations for the respective type parameters.
For example, given
// dedup returns a copy of the argument slice with any duplicate entries removed. func dedup[S ~[]E, E comparable](S) S { … } type Slice []int var s Slice s = dedup(s) // same as s = dedup[Slice, int](s)
the variable
s
of typeSlice
must be assignable to the function parameter typeS
for the program to be valid. To reduce complexity, type inference ignores the directionality of assignments, so the type relationship betweenSlice
andS
can be expressed via the (symmetric) type equationSlice ≡
A
S
(orS ≡
A
Slice
for that matter), where theA
in≡
A
indicates that the LHS and RHS types must match per assignability rules (see the section on type unification for details). Similarly, the type parameterS
must satisfy its constraint~[]E
. This can be expressed asS ≡
C
~[]E
whereX ≡
C
Y
stands for “X satisfies constraint Y”. These observations lead to a set of two equationsSlice ≡A S (1) S ≡C ~[]E (2)which now can be solved for the type parameters
S
andE
. From (1) a compiler can infer that the type argument forS
isSlice
. Similarly, because the underlying type ofSlice
is[]int
and[]int
must match[]E
of the constraint, a compiler can infer thatE
must beint
. Thus, for these two equations, type inference infersS ➞ Slice E ➞ int
Quotes from The Go Programming Language Specification Version of August 2, 2023