Golang Release 1.21: cmp
- 4 minutes read - 784 wordsNew package in Go standard library that makes easier to compare ordered types.

As the new release of Go came this summer, many of us started to look for the improvements inside its ecosystem. Many new features were introduced, including updates to the tool command to support backward and forward compatibility. New packages appeared inside the Standard Library, including maps and slices. In this article we are covering improvements introduced with the new cmp package.
The new package offers three new functions. All of them rely on Generics,
a feature introduced in Go version 1.18, which has opened up possibilities for many new features. The cmp
package introduces
new functions for comparing values of Ordered
constraint.
Let’s dive into each of them.
Ordered constraint and Compare function
The constraint Ordered
encompasses all types that support comparison operators for values, specifically, <
, <=
,
>=
and >
. This includes all numeric types in Go, as well as strings
.
Ordered Constraint
type Ordered interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
~string
}
Once we understand what the Ordered
constraint includes, we can focus on the first function from the cmp
package,
which is the Compare
function. Below, you can find its signature:
Compare Function
// Compare returns
//
// -1 if x is less than y,
// 0 if x equals y,
// +1 if x is greater than y.
// ...
func Compare[T Ordered](x, y T) int
The signature, along with the function description, makes it much easier to understand. The Compare
function expects
two arguments of the same type, compares their values, and returns a result that represents the comparison status:
- -1 if the first argument is less than the second.
- 0 if the arguments’ values are equal.
- 1 if the first argument is greater than the second.
Let’s prove such claim:
Compare numerals
fmt.Println(cmp.Compare(1, 2))
// Output:
// -1
fmt.Println(cmp.Compare(1, 1))
// Output:
// 0
fmt.Println(cmp.Compare(2, 1))
// Output:
// 1
Compare strings
fmt.Println(cmp.Compare("abc", "def"))
// Output:
// -1
fmt.Println(cmp.Compare("qwe", "qwe"))
// Output:
// 0
fmt.Println(cmp.Compare("abcde", "abcc"))
// Output:
// 1
Above, we can see practical examples of the Compare
function for both numerals
and strings
. Indeed, the return
values can only belong to the set of numbers {-1, 0, 1}
, as defined in the description.
Function Less
In addition to the function Compare, we got another, similar function Less. Although it’s rather easy to understand what is used for, let’s check its signature:
Function Less
func Less[T Ordered](x, y T) bool
Again, this method expects two arguments of the same type that must adhere to the Ordered
constraint. It returns the
boolean value true
if the first argument is less than the second one.
Less function with numerals
fmt.Println(cmp.Compare(1, 2))
// Output:
// -1
fmt.Println(cmp.Compare(1, 1))
// Output:
// 0
fmt.Println(cmp.Compare(2, 1))
// Output:
// 1
Less function with strings
fmt.Println(cmp.Less("abc", "def"))
// Output:
// true
fmt.Println(cmp.Less("qwe", "qwe"))
// Output:
// false
fmt.Println(cmp.Less("abcde", "abcc"))
// Output:
// false
Bonus: functions min and max
In addition to the functions mentioned in the cmp
package, the new Go release introduced two new built-in functions: min
and max
. They are also based on Generics and can be used without importing any package, just like other built-in functions. Below, you can find their signatures:
Min function
func min[T cmp.Ordered](x T, y ...T) T
Max function
func max[T cmp.Ordered](x T, y ...T) T
Both min
and max
functions are variadic functions, and they expect at least one argument. As you can see, only the
x
argument of type T
is required, and the y
argument is a trailing argument that can accept many or no values of
the same type T
. The result of these functions is a single value of the same type T
, representing the minimum or
maximum of all the values. Let’s check some examples:
Examples with numerals
fmt.Println(min(1, 2, 3))
// Output:
// 1
fmt.Println(max(1, 2, 3))
// Output:
// 3
fmt.Println(min(1))
// Output:
// 1
fmt.Println(max(1))
// Output:
// 1
Examples with strings
fmt.Println(min("abc", "def"))
// Output:
// abc
fmt.Println(max("abc", "def"))
// Output:
// def
fmt.Println(min("qwe", "qwe", "qwe"))
// Output:
// qwe
fmt.Println(max("qwe"))
// Output:
// qwe
In all the examples above, we can see how the new functions behave in various situations. This includes their normal behavior with only one argument, as well as when more than two arguments are provided.
Conclusion
New version of Golang, 1.21, delivered many new updates, affecting standard library as well. In this article we checked how functions from cmp packages work. Those new methods give us now possibility to easily compare any ordered types in Go.