I always try to add my own commentary, examples, or other explanation in these emails.
Today I’m not really sure what to add.
min
and max
are such basic, and self-evident features, that the biggest surprise about these is that they’re such recent additions to the language. They were added just barely a year ago, with Go 1.21.
I will add a bit after we read about min
and max
, though.
Min and max
The built-in functions
min
andmax
compute the smallest—or largest, respectively—value of a fixed number of arguments of ordered types. There must be at least one argument [Go 1.21].The same type rules as for operators apply: for ordered arguments
x
andy
,min(x, y)
is valid ifx
+y
is valid, and the type ofmin(x, y)
is the type ofx + y
(and similarly formax
). If all arguments are constant, the result is constant.var x, y int m := min(x) // m == x m := min(x, y) // m is the smaller of x and y m := max(x, y, 10) // m is the larger of x and y but at least 10 c := max(1, 2.0, 10) // c == 10.0 (floating-point kind) f := max(0, float32(x)) // type of f is float32 var s []string _ = min(s...) // invalid: slice arguments are not permitted t := max("", "foo", "bar") // t == "foo" (string kind)
For numeric arguments, assuming all NaNs are equal,
min
andmax
are commutative and associative:min(x, y) == min(y, x) min(x, y, z) == min(min(x, y), z) == min(x, min(y, z))
For floating-point arguments negative zero, NaN, and infinity the following rules apply:
x y min(x, y) max(x, y) -0.0 0.0 -0.0 0.0 // negative zero is smaller than (non-negative) zero -Inf y -Inf y // negative infinity is smaller than any other number +Inf y y +Inf // positive infinity is larger than any other number NaN y NaN NaN // if any argument is a NaN, the result is a NaN
For string arguments the result for min is the first argument with the smallest (or for max, largest) value, compared lexically byte-wise:
min(x, y) == if x <= y then x else y min(x, y, z) == min(min(x, y), z)
There’s one other function I’d like to call your attention to, that has some similiarities. It’s not part of the spec, but was added to the standard library at the same time, and that is cmp.Or
. cmp.Or
works like min
and max
, in that it takes one or more arguments of the same type, but rather than returning the minimum or maximum, it returns the first of the arguments to not equal the type’s zero value.
a := min(0, 3, 4, 1) // 0
b := max(0, 3, 4, 1) // 4
c := cmp.Or(0, 3, 4, 1) // 3
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)