What if your code could warn you every time you forget to handle a case?
Why Enum with when exhaustive check in Kotlin? - Purpose & Use Cases
Imagine you have a list of tasks, each with a status like "To Do", "In Progress", or "Done". You want to write code that does something different for each status. Without enums and exhaustive checks, you might write many if-else statements, and it's easy to forget one status or add a new one and miss updating your code.
Manually checking each status with if-else is slow and error-prone. You might forget a case, causing bugs that are hard to find. When you add a new status, you have to hunt through your code to update every check. This makes your code fragile and hard to maintain.
Using enums with a when expression that is exhaustive means Kotlin forces you to handle every possible status. If you miss one, the compiler will warn you. This makes your code safer, easier to read, and easier to update when you add new statuses.
if (status == "To Do") { /*...*/ } else if (status == "In Progress") { /*...*/ } // forgot "Done" case
when (status) {
Status.TODO -> /*...*/
Status.IN_PROGRESS -> /*...*/
Status.DONE -> /*...*/
}This lets you write clear, safe code that automatically reminds you to handle every possible case, preventing bugs before they happen.
Think of a traffic light system with states like RED, YELLOW, and GREEN. Using enums with exhaustive when ensures your program reacts correctly to every light color, and if a new color is added, you won't forget to update your logic.
Manual checks can miss cases and cause bugs.
Enums with exhaustive when force you to handle all cases.
This leads to safer, clearer, and easier-to-maintain code.
Practice
when expression require when used with an enum class?Solution
Step 1: Understand enum and when usage
Kotlin enums define fixed values. Thewhenexpression can check these values.Step 2: Check compiler requirements for exhaustive when
Kotlin requires all enum cases to be handled inwhento be exhaustive, avoiding missing cases.Final Answer:
All enum cases must be handled to ensure exhaustive checking. -> Option AQuick Check:
Exhaustive when = all enum cases handled [OK]
- Forgetting to handle all enum values
- Using else unnecessarily when all cases are covered
- Assuming when can't be exhaustive with enums
when expression that exhaustively checks all values of this enum?enum class Direction { NORTH, SOUTH, EAST, WEST }Solution
Step 1: Check all enum values handled
when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" } lists all four enum values with their results, no else needed.Step 2: Verify syntax correctness
when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" } uses correct when syntax with enum constants and returns strings.Final Answer:
when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" } -> Option AQuick Check:
All enum cases handled without else = when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" } [OK]
- Using else when all enum cases are handled
- Missing some enum values in when
- Using wrong types in when branches
enum class Light { RED, GREEN, YELLOW }
fun signalMessage(light: Light) = when(light) {
Light.RED -> "Stop"
Light.GREEN -> "Go"
Light.YELLOW -> "Caution"
}
fun main() {
println(signalMessage(Light.YELLOW))
}Solution
Step 1: Identify the enum value passed
The function is called withLight.YELLOW.Step 2: Match enum value in when expression
The when expression returns "Caution" forLight.YELLOW.Final Answer:
Caution -> Option CQuick Check:
Light.YELLOW maps to "Caution" [OK]
- Confusing enum values with strings
- Assuming else is needed for exhaustive when
- Expecting compilation error due to missing else
enum class Status { SUCCESS, ERROR, LOADING }
fun getStatusMessage(status: Status) = when(status) {
Status.SUCCESS -> "Done"
Status.ERROR -> "Failed"
}
Solution
Step 1: Check enum cases handled in when
OnlyStatus.SUCCESSandStatus.ERRORare handled;Status.LOADINGis missing.Step 2: Understand Kotlin's exhaustive when requirement
When used as expression, all enum cases must be handled or else an else branch is needed.Final Answer:
Not all enum cases handled in when expression -> Option BQuick Check:
Missing enum case causes compilation error [OK]
- Assuming else is optional when missing enum cases
- Ignoring missing enum values in when
- Thinking function return type causes error
getDayType to use an exhaustive when expression without an else branch?enum class Day { MON, TUE, WED, THU, FRI, SAT, SUN }
fun getDayType(day: Day): String = when(day) {
Day.SAT, Day.SUN -> "Weekend"
Day.MON, Day.TUE, Day.WED, Day.THU, Day.FRI -> "Weekday"
}Solution
Step 1: Analyze current when branches
The branches cover Day.SAT, Day.SUN and Day.MON, Day.TUE, Day.WED, Day.THU, Day.FRI, which includes all seven enum values.Step 2: Verify Kotlin's exhaustive when rules
Kotlin considers thewhenexhaustive if all enum cases are explicitly covered across branches, even when grouped with commas in the same branch. Noelsebranch is needed.Final Answer:
Keep combined branches as is; Kotlin treats it as exhaustive. -> Option DQuick Check:
Grouped coverage of all enum cases = exhaustive without else [OK]
- Thinking combined branches don't count as exhaustive
- Believing you must use separate branches for each enum value
- Unnecessarily adding an else branch
Ready to prove it?
Pass the test and this pattern moves unknown
