The when Expression
Kotlin's replacement for switch statements — far more flexible, and just as safe as if when used as an expression.
読了時間 2 分
when is Kotlin's equivalent of a switch statement, but it drops nearly every limitation switch carries in other languages: no fall-through, no restriction to a handful of primitive types, and — like if — it can be used as an expression that produces a value.
Basic matching
val dayNumber = 3
val dayName = when (dayNumber) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
else -> "Unknown"
}
println(dayName) // WednesdayEach branch runs only its own code — there's no need for a break, and no risk of accidentally falling into the next branch, a classic switch bug in other languages.
Matching multiple values, or a range
A single branch can cover several values, separated by commas, or an entire range:
val grade = when (score) {
in 90..100 -> "A"
in 80..89 -> "B"
in 70..79 -> "C"
0, 1, 2 -> "Needs review"
else -> "F"
}Matching without any subject at all
when doesn't require a value to match against — used this way, it behaves like a cleaner chain of if/else if:
val temperature = 15
val description = when {
temperature < 0 -> "Freezing"
temperature < 15 -> "Cold"
temperature < 25 -> "Mild"
else -> "Hot"
}
println(description) // Mild (15 hits the "< 25" branch, since 15 isn't < 15)Each branch is a boolean condition evaluated top to bottom, and the first one that's true wins.
Matching types
when can also check a value's type directly, using is — and inside each branch, the value is automatically smart-cast to that type:
fun describe(value: Any): String = when (value) {
is Int -> "An integer: $value"
is String -> "A string of length ${value.length}"
is Boolean -> "A boolean: $value"
else -> "Something else"
}Notice value.length inside the String branch — no cast needed, because when already proved value is a String there.
Exhaustiveness
When when is used as an expression (its result is assigned or returned), the compiler requires it to be exhaustive — every possible input must be handled, usually via else. This matters most once you reach sealed classes and enums later in this course: for those types, Kotlin can verify every case is covered without even needing an else branch, so adding a new case later causes a compile error everywhere you forgot to handle it, rather than a silent bug.
With branching covered by if and when, the next lesson turns to repetition: loops and the ranges that power a lot of Kotlin's iteration.