Min and max
Min and max (최솟값과 최댓값)
정해진 개수의 인자들 중에서 가장 작은 값, 또는 가장 큰 값을 구하고 싶을 때가 많죠. 예를 들어 세 숫자 중 최댓값을 꺼내야 한다면, 매번 비교를 직접 쓰느라 코드가 지저분해지기 쉬운데요. Go에는 이걸 그냥 함수로 해결해 주는 내장 함수가 있어요. 바로 min과 max입니다. 고정된 개수의 인자(argument) 중에서 가장 작은, 혹은 각각 가장 큰 값을 계산해 주는 내장 함수예요.
출처: Go Specification
본문
내장 함수 min과 max는 정렬 가능한 타입(ordered types)의 인자들이 일정한 개수 있을 때, 그중에서 각각 가장 작은 값과 가장 큰 값을 계산해요. 인자는 최소한 하나는 있어야 해요 [Go 1.21].
연산자(operator)와 똑같은 타입 규칙이 적용돼요. 즉 정렬 가능한 인자 x와 y에 대해 min(x, y)가 유효하려면 x + y가 유효해야 하고, min(x, y)의 타입은 x + y의 타입과 같아요 (max도 마찬가지예요). 모든 인자가 상수라면 결과도 상수예요.
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)
숫자 인자의 경우, 모든 NaN이 서로 같다고 가정하면 min과 max는 교환 법칙(commutative)과 결합 법칙(associative)을 만족해요.
min(x, y) == min(y, x)
min(x, y, z) == min(min(x, y), z) == min(x, min(y, z))
부동소수점(floating-point) 인자의 경우, 음의 영(negative zero), NaN, 무한대(infinity)에 대해서는 다음 규칙이 적용돼요.
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
문자열 인자의 경우, min의 결과는 바이트 단위로 어휘 비교(lexically byte-wise)했을 때 가장 작은 값(또는 max는 가장 큰 값)을 가진 첫 번째 인자가 돼요.
min(x, y) == if x <= y then x else y
min(x, y, z) == min(min(x, y), z)
더 알아보기
- Go 1.21에서 내장
min/max가 도입됐어요. 그 전에는 이런 비교를 직접 구현하거나 외부 헬퍼에 의존해야 했죠. - 부동소수점에서는
-0.0과0.0을 서로 다르게 취급하고, NaN이 하나라도 섞이면 결과가 NaN이 된다는 점을 기억해 두면 좋아요. min/max의 타입 규칙이 일반 연산자와 같다는 점은, 타입 추론이 어떻게 흘러가는지 이해할 때 유용한 단서예요.