Kotlin
when with sealed
Learn exhaustive branching on sealed classes with when.
when and exhaustive
When you use when on a sealed class, the compiler knows all subtypes, so exhaustive branching is possible. No else branch is needed.
Example: when (s) { is Loading -> "loading"; is Done -> "done" }. This expression covers all subtypes, returns a value and needs no else. If you add a new subtype, the compiler flags the when as incomplete and forces you to update all branches. This is the biggest safety advantage of sealed classes.
Why else is not needed
When you use when on a sealed class you do not need to write else. The compiler knows all subtypes and checks that the branches are complete.
Example: fun describe(s: Status): String = when (s) { is Loading -> "loading"; is Done -> "done" }. This function returns a String and no branch is missing. If tomorrow you add an Error subtype to Status, the compiler flags describe as incomplete; you cannot forget the new case. This safety is impossible with open hierarchies.
Exercise Branch on Status with when
Define a sealed class named Status. Add two subtypes: object Loading : Status() and object Done : Status(). Write a function describe(s: Status): String whose body uses when (s) to return "loading" for Loading and "done" for Done. In main print describe(Loading) and describe(Done) with println.
Show example solution
sealed class Status
object Loading : Status()
object Done : Status()
fun describe(s: Status): String {
return when (s) {
is Loading -> "loading"
is Done -> "done"
}
}
fun main() {
println(describe(Loading))
println(describe(Done))
}
Test yourself
-
Match the when + sealed pattern
- when (s) {
- Branching
- is Loading
- Type check
- -> "loading"
- Branch body
- no else needed
- Exhaustive safety
-
When using <code>when</code> on a sealed class, why is the <code>else</code> branch usually not needed?
- Because a sealed class is abstract
- Because the compiler knows all subtypes and completes the branches
- Because when accepts only one branch
- Because a sealed class has no subtypes
Show answer
Because the compiler knows all subtypes and completes the branches — The compiler knows all subtypes, so exhaustive branching is possible.
-
Complete the when expression
fun describe(s: Status): String {
return ____ (s) {
is Loading -> "loading"
is Done -> "done"
}
}
Show answer
fun describe(s: Status): String {
return when (s) {
is Loading -> "loading"
is Done -> "done"
}
}
Next lesson: Sealed and data