What is golang.org/x/exp/constraints, how does it relate to cmp.Ordered, and how do you define your own numeric constraint?
Question 137MediumGo 1.22 to 1.25
x/exp/constraints was the experimental home for common constraints: Signed, Unsigned, Integer, Float, Complex and Ordered. Only Ordered moved into the standard library, as cmp.Ordered in Go 1.21. The rest stayed in x/exp, because the team was unsure of the right granularity and naming. Many teams define their own constraints instead of taking an x/exp dependency.
// cmp.Ordered (std, Go 1.21):
// ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ... | ~uintptr |
// ~float32 | ~float64 | ~string
type Integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Float interface{ ~float32 | ~float64 }
type Number interface{ Integer | Float }
func Mean[T Number](xs []T) float64 {
if len(xs) == 0 {
return 0
}
var sum T
for _, x := range xs {
sum += x
}
return float64(sum) / float64(len(xs))
}
Gotchas:
sumof type T can overflow for small ints such asint8. Consider accumulating infloat64orint64.cmp.Orderedincludes~stringbut not complex numbers or booleans.- Embedding constraint interfaces in a union (
Integer | Float) is allowed only because neither has methods.
More on Generics
- Q135Design a thread-safe generic cache with a
GetOrLoadmethod. What concurrency pitfalls exist? - Q136Write generic
Map,FilterandReducefor slices. Why aren't they in the standard library'sslicespackage? - Q138Explain the
cmppackage:Compare,Less,Or. How do you do a multi-key sort, and how is NaN handled? - Q139Which generic helpers in
slicesandmapsshould a senior Go developer know, and what are their gotchas? - Q140How do generics combine with Go 1.23 iterators (
iter.Seq)? Write lazyFilterandMapadapters and explain theyieldcontract. - Q141What is
iter.Pull, and when do you need it? Implement a genericZip.