위 예제에서 else 가지를 없애면 ‘‘when’ expression must be exhaustive, add necessary ‘else’ branch’ 컴파일 타입 오류가 발생한다(when이 가능한 모든 경우를 처리해야 하므로 else 가지를 추가하라는 뜻). when 식을 문처럼 취급하는 경우(즉, when의 결과를 사용하지 않는 경우)에만 else 가지를 생략할 수 있다. 이 경우 매치와 일치하지 않으면 아무 일도 일어나지 않고 when 문이 끝난다.
다음 예제의 Coordinates는 아톰 28에서 다룬 프로퍼티 접근자를 사용해 프로퍼티 값이 변한다는 사실을 알려준다. when 식은 inputs의 각 줄을 처리한다.
WhenExpressions/AnalyzeInput.kt
package whenexpressions
import atomictest.*
class Coordinates {
var x: Int = 0
set(value) {
trace("x gets $value")
field = value
}
var y: Int = 0
set(value) {
trace("y gets $value")
field = value
}
override fun toString() = "($x, $y)"
}
fun processInputs(inputs: List<String>) {
val coordinates = Coordinates()
for (input in inputs) {
when (input) { // [1]
"up", "u" -> coordinates.y-- // [2]
"down", "d" -> coordinates.y++
"left", "l" -> coordinates.x--
"right", "r" -> { // [3]
trace("Moving right")
coordinates.x++
}
"nowhere" -> {} // [4]
"exit" -> return // [5]
else -> trace("bad input: $input")
}
}
}
fun main() {
processInputs(listOf("up", "d", "nowhere",
"left", "right", "exit", "r"))
trace eq """
y gets -1
y gets 0
x gets -1
Moving right
x gets 0
"""
}
• [1] input을 여러 선택지와 비교한다.
• [2] 콤마를 써서 한 가지에 여러 값을 나열해도 된다. 여기서는 사용자가 "up" 또는 "u"를 입력한 경우 위로 움직인다.
• [3] 가지에서 화살표 오른쪽에 여러 동작을 수행해야 할 경우에는 블록(중괄호로 여러 문장을 묶음)을 사용해야 한다.
• [4] ‘아무 일도 하지 않음’은 빈 중괄호로 표현한다.
• [5] when 문의 가지에서 자신을 둘러싼 함수를 반환시키는 것도 가능하다. 여기서 return은 processInputs()를 끝낸다.