cmp is a small generics-era package: three functions and one type constraint for ordering and defaulting values, added in Go 1.21.
Examples
Compare returns a three-way result usable directly as a sort comparator. Less is a plain boolean shortcut for the same ordering.
fmt.Println(cmp.Compare(3, 5))
fmt.Println(cmp.Compare(5, 5))
fmt.Println(cmp.Compare(5, 3))
fmt.Println(cmp.Less(3, 5))
fmt.Println(cmp.Less("banana", "apple"))Output
-1
0
1
true
falseOr walks its arguments and returns the first one that isn't the type's zero value, a compact way to fall back to a default.
type Config struct {
Name string
}
func label(c Config) string {
return cmp.Or(c.Name, "unnamed")
}
fmt.Println(label(Config{Name: "worker"}))
fmt.Println(label(Config{}))
port := cmp.Or(0, 0, 8080)
fmt.Println(port)Output
worker
unnamed
8080Compare composes naturally into a multi-key sort: fall through to the next field only when the current one ties.
type Person struct {
Name string
Age int
}
people := []Person{
{"Bea", 30},
{"Alan", 25},
{"Cy", 25},
}
slices.SortFunc(people, func(a, b Person) int {
if c := cmp.Compare(a.Age, b.Age); c != 0 {
return c
}
return cmp.Compare(a.Name, b.Name)
})
for _, p := range people {
fmt.Println(p.Name, p.Age)
}Output
Alan 25
Cy 25
Bea 30cmp.Ordered is the type constraint behind Compare and Less. Writing a generic function against it accepts any built-in ordered type.
func Max[T cmp.Ordered](a, b T) T {
if cmp.Less(a, b) {
return b
}
return a
}
fmt.Println(Max(3, 7))
fmt.Println(Max("go", "rust"))Output
7
rust| Function | Description |
|---|---|
Compare[T Ordered](x, y T) int cmp.Compare(3, 5) | Returns -1 if x < y, 0 if x == y, 1 if x > y |
Less[T Ordered](x, y T) bool cmp.Less(3, 5) | Reports whether x sorts before y |
Or[T comparable](vals ...T) T cmp.Or(0, 0, 7) | Returns the first non-zero-value argument, or the zero value if every argument is zero |
Ordered func Max[T cmp.Ordered](a, b T) T | Type constraint satisfied by any ordered type: integers, floats, and strings |
Related: Generics slices Sorting