1. 코틀린의 조건문
- 코틀린은 두 가지 주요 조건문인
if와when을 제공합니다. - 자바와 달리 코틀린에서 이 조건문들은 표현식(expression)으로 사용될 수 있어 값을 반환할 수 있습니다.
- 여기서 표현식이란 값을 반환하는 코드 블록을 의미합니다.
- 반대로 구문(statement)은 값을 반환하지 않는 코드 블록을 의미합니다.
1.1 If 표현식
- 코틀린에서
if는 표현식이므로 값을 반환할 수 있습니다. - 이로 인해 자바의 삼항 연산자(
condition ? then : else)가 필요 없습니다.
1.1.1 기본 사용법
// 기본 형태
var max = a
if (a < b) max = b
// else 사용
if (a > b) {
max = a
} else {
max = b
}
// 표현식으로 사용
max = if (a > b) a else b
// else if 사용
val maxLimit = 1
val maxOrLimit = if (maxLimit > a) maxLimit else if (a > b) a else b
println("max is $max")
println("maxOrLimit is $maxOrLimit")
1.1.2 블록을 포함한 if 표현식
val max = if (a > b) {
print("Choose a")
a // 블록의 마지막 표현식이 반환값이 됩니다
} else {
print("Choose b")
b
}
if를 표현식으로 사용할 때(값을 반환하거나 변수에 할당할 때)는else분기가 필수입니다.if분기에 블록을 사용하는 경우 블록의 마지막 식이 그 분기의 값이 됩니다.
1.2 When 표현식
- if와 마찬가지로 값을 반환할 수 있는 표현식입니다.
when은 자바의switch와 유사하지만 더 강력한 기능을 제공합니다.- 여러 조건에 따라 코드를 실행하는 조건부 표현식입니다.
1.2.1 기본 사용법
val x = 2
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> print("x is neither 1 nor 2")
}
- 자바와 달리 각 분기의 끝에
break를 명시할 필요가 없습니다.
1.2.2 표현식과 구문으로서의 when
val text = when (x) {
1 -> "x == 1"
2 -> "x == 2"
else -> "x is neither 1 nor 2"
}
- 위는 표현식으로 사용(값을 반환)한 예시입니다.
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> print("x is neither 1 nor 2")
}
- 구문으로 사용 (값을 반환하지 않음)한 예시입니다.
1.2.3 주체가 있는 when과 없는 when
when(x) { ... }
- 위는 주체가 있는 when의 예시입니다.
- when 식의 인자로 아무 객체나 사용할 수 있습니다.
- 인자로 받은 객체가 각 분기 조건에 있는 객체와 같은지 비교합니다.
- when 식은 인자 값과 일치하는 조건 값을 찾을 때까지 각 분기를 검사합니다.
- 분기 조건에 있는 객체를 비교할 때 동등성을 사용합니다.
when {
a > b -> "a is greater than b"
a < b -> "a is less than b"
else -> "a is equal to b"
}
- 주체가 없는 when의 예시입니다.
- when에 아무 인자가 없으면 각 분기의 조건이 불리언 결과를 계산하는 식이어야 합니다.
경고
when을 표현식으로 사용할 때는 모든 가능한 경우를 처리해야 합니다. 즉, 철저해야(exhaustive) 합니다. 모든 경우를 처리하지 않으면 컴파일러는 오류를 발생시킵니다.
1.2.4 다양한 when 사용법
- 여러 조건을 한 줄에 콤마로 결합:
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
- 임의 표현식을 조건으로 사용:
when (x) {
s.toInt() -> print("s encodes x")
else -> print("s does not encode x")
}
- 범위나 컬렉션 내 포함 여부 확인:
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
- 타입 확인(스마트 캐스트 지원):
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix") // x가 자동으로 String으로 캐스팅됨
else -> false
}
- if-else if 체인 대체:
when {
x.isOdd() -> print("x is odd")
y.isEven() -> print("y is even")
else -> print("x+y is odd")
}
- 주체 변수 캡처:
fun Request.getBody() =
when (val response = executeRequest()) {
is Success -> response.body
is HttpError -> throw HttpException(response.status)
}