Bird
Raised Fist0
Kotlinprogramming~15 mins

Enum with when exhaustive check in Kotlin - Deep Dive

Choose your learning style10 modes available
Overview - Enum with when exhaustive check
What is it?
An enum in Kotlin is a special type that holds a fixed set of constants. The when expression is a control flow structure that lets you choose actions based on values. When used with enums, Kotlin can check if all possible enum values are covered, making the when expression exhaustive. This means you handle every possible case, avoiding mistakes where some enum values are forgotten.
Why it matters
Without exhaustive checks, you might miss handling some enum values, causing bugs or unexpected behavior. Exhaustive when expressions help catch these mistakes at compile time, making your code safer and more reliable. This is especially important in apps where every state or option must be handled correctly, like user roles or app modes.
Where it fits
Before learning this, you should understand basic Kotlin syntax, enums, and the when expression. After mastering this, you can explore sealed classes for more complex exhaustive checks and advanced Kotlin control flow features.
Mental Model
Core Idea
An exhaustive when expression with enums ensures every possible enum value is handled, preventing missing cases.
Think of it like...
It's like checking off every item on a grocery list before leaving the store; you don't want to forget anything important.
┌───────────────┐
│   Enum Type   │
│  (fixed set)  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│   when(value) │
│ ┌───────────┐ │
│ │ case A    │ │
│ │ case B    │ │
│ │ case C    │ │
│ └───────────┘ │
└───────────────┘
All cases covered → Exhaustive
Build-Up - 6 Steps
1
FoundationUnderstanding Kotlin Enums Basics
🤔
Concept: Learn what enums are and how to define them in Kotlin.
In Kotlin, an enum class defines a type with a fixed set of constants. For example: enum class Direction { NORTH, SOUTH, EAST, WEST } Each constant represents a possible value of Direction.
Result
You can create variables of type Direction and assign one of the constants, like Direction.NORTH.
Knowing enums lets you represent limited sets of options clearly and safely in your code.
2
FoundationUsing when Expression Basics
🤔
Concept: Learn how to use the when expression to choose actions based on values.
The when expression in Kotlin works like a switch-case. Example: val dir = Direction.NORTH when (dir) { Direction.NORTH -> println("Going north") Direction.SOUTH -> println("Going south") else -> println("Other direction") } It matches the value and runs the matching block.
Result
The program prints "Going north" if dir is Direction.NORTH.
When expressions let you write clear, readable code that reacts to different values.
3
IntermediateExhaustive when with Enums
🤔Before reading on: do you think Kotlin requires all enum cases in when expressions? Commit to yes or no.
Concept: Kotlin can enforce that when expressions cover all enum values, making them exhaustive.
If you cover all enum constants in when without an else branch, Kotlin treats the when as exhaustive. For example: when (dir) { Direction.NORTH -> println("North") Direction.SOUTH -> println("South") Direction.EAST -> println("East") Direction.WEST -> println("West") } No else is needed because all cases are handled.
Result
The compiler checks all enum values are covered, preventing missing cases.
Exhaustive when expressions catch missing enum cases at compile time, reducing runtime errors.
4
IntermediateWhy else Branch is Needed or Not
🤔Before reading on: If you miss one enum case in when, will Kotlin force you to add else? Commit to yes or no.
Concept: When not all enum cases are covered, Kotlin requires an else branch to handle the rest.
Example missing a case: when (dir) { Direction.NORTH -> println("North") Direction.SOUTH -> println("South") else -> println("Other") } Here, EAST and WEST are not listed, so else covers them. Without else, compiler error occurs.
Result
You must add else or cover all cases to compile successfully.
This rule forces you to think about all enum values, improving code safety.
5
AdvancedUsing when as an Expression for Exhaustiveness
🤔Before reading on: Do you think when can return a value only if exhaustive? Commit to yes or no.
Concept: When expressions can return values only if they are exhaustive, ensuring all cases produce a result.
Example: val message = when (dir) { Direction.NORTH -> "Going north" Direction.SOUTH -> "Going south" Direction.EAST -> "Going east" Direction.WEST -> "Going west" } If any case is missing, compiler error occurs because message might not get a value.
Result
You get a guaranteed value from when, avoiding null or uninitialized variables.
Exhaustiveness ensures safe value assignment from when expressions.
6
ExpertCompiler Internals for Exhaustive Check
🤔Before reading on: Do you think Kotlin compiler tracks enum completeness by name or by type? Commit to your answer.
Concept: The Kotlin compiler analyzes the enum type and the when branches to verify all enum constants are covered without else.
At compile time, Kotlin matches each when branch against enum constants. If any constant is missing, and no else is present, it raises an error. This check is part of Kotlin's smart control flow analysis to prevent runtime errors.
Result
Compile-time safety for enum handling without runtime overhead.
Understanding compiler checks helps write safer, cleaner Kotlin code and debug exhaustiveness errors.
Under the Hood
Kotlin's compiler inspects the enum class to get all possible constants. When compiling a when expression on that enum, it compares the branches against these constants. If all constants are matched and no else branch exists, the when is marked exhaustive. This allows when to be used as an expression returning a value safely. If any constant is missing, the compiler demands an else branch to cover the rest. This static check prevents runtime errors from unhandled enum cases.
Why designed this way?
This design was chosen to improve code safety and clarity. Enums represent fixed sets, so the compiler can know all possible values. Enforcing exhaustive when expressions avoids bugs where developers forget to handle some enum cases. Alternatives like requiring else always would reduce safety, and no checks would allow silent bugs. Kotlin balances flexibility and safety by allowing else or full coverage.
┌───────────────┐
│   Enum Class  │
│ ┌───────────┐ │
│ │ Constants │ │
│ │ N, S, E, W│ │
│ └────┬──────┘ │
└──────┼────────┘
       │
       ▼
┌───────────────┐
│  when(expr)   │
│ ┌───────────┐ │
│ │ Branches  │ │
│ │ N, S, E, W│ │
│ └────┬──────┘ │
└──────┼────────┘
       │
       ▼
┌─────────────────────────┐
│ Exhaustive?             │
│ Yes → when is expression │
│ No → else required       │
└─────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does Kotlin always require an else branch in when expressions with enums? Commit to yes or no.
Common Belief:Kotlin always requires an else branch in when expressions to handle unknown cases.
Tap to reveal reality
Reality:Kotlin only requires else if not all enum constants are covered. If all are covered, else is not needed.
Why it matters:Adding unnecessary else branches can hide missing enum cases and reduce code clarity.
Quick: Can you use when as an expression returning a value without covering all enum cases? Commit to yes or no.
Common Belief:You can return a value from when without covering all enum cases if you add else.
Tap to reveal reality
Reality:Yes, but the else branch must handle all missing cases. Without else or full coverage, compiler error occurs.
Why it matters:Missing coverage or else causes compile errors, preventing unsafe code.
Quick: Does Kotlin's exhaustive check work with any sealed class the same as enums? Commit to yes or no.
Common Belief:Exhaustive when checks only work with enums, not sealed classes.
Tap to reveal reality
Reality:Exhaustive when checks also work with sealed classes, which have a fixed set of subclasses.
Why it matters:Knowing this helps write safer code with sealed classes, not just enums.
Quick: If you add a new enum constant later, will Kotlin warn you about missing when cases? Commit to yes or no.
Common Belief:Kotlin does not warn about missing when cases after adding new enum constants.
Tap to reveal reality
Reality:Kotlin will produce a compile error if a when expression is no longer exhaustive after adding new enum constants.
Why it matters:This helps maintain code correctness as enums evolve.
Expert Zone
1
Exhaustive when expressions can be used as statements or expressions, but only expressions require full coverage.
2
When using enums with associated properties or methods, exhaustive checks still only consider constants, not their data.
3
Compiler exhaustiveness checks also work with smart casts and nullable enums, but require careful handling of null cases.
When NOT to use
Avoid relying solely on enums and exhaustive when for very large or dynamic sets of values. Instead, use sealed classes or polymorphism for more flexible hierarchies. Also, if enum values change frequently, exhaustive when can become cumbersome.
Production Patterns
In production Kotlin code, exhaustive when with enums is used to handle state machines, user roles, UI modes, and configuration options. Developers rely on compiler checks to prevent missing cases, improving app stability and maintainability.
Connections
Sealed Classes in Kotlin
Builds-on
Understanding exhaustive when with enums helps grasp sealed classes, which extend this idea to class hierarchies for safer control flow.
Pattern Matching in Functional Languages
Same pattern
Exhaustive checks in Kotlin when expressions are similar to pattern matching in languages like Haskell or Scala, ensuring all cases are handled.
Decision Trees in Machine Learning
Conceptual similarity
Both exhaustive when expressions and decision trees systematically cover all possible cases to make safe, complete decisions.
Common Pitfalls
#1Missing enum cases in when without else branch
Wrong approach:when (dir) { Direction.NORTH -> println("North") Direction.SOUTH -> println("South") } // Missing EAST and WEST, no else branch
Correct approach:when (dir) { Direction.NORTH -> println("North") Direction.SOUTH -> println("South") Direction.EAST -> println("East") Direction.WEST -> println("West") }
Root cause:Not realizing Kotlin requires all enum constants to be covered or an else branch to compile.
#2Using else branch unnecessarily when all enum cases are covered
Wrong approach:when (dir) { Direction.NORTH -> println("North") Direction.SOUTH -> println("South") Direction.EAST -> println("East") Direction.WEST -> println("West") else -> println("Unknown") }
Correct approach:when (dir) { Direction.NORTH -> println("North") Direction.SOUTH -> println("South") Direction.EAST -> println("East") Direction.WEST -> println("West") }
Root cause:Not knowing that else is optional if all enum cases are handled, leading to redundant code.
#3Trying to use when as expression without full coverage or else
Wrong approach:val message = when (dir) { Direction.NORTH -> "North" Direction.SOUTH -> "South" } // Missing EAST and WEST, no else branch
Correct approach:val message = when (dir) { Direction.NORTH -> "North" Direction.SOUTH -> "South" Direction.EAST -> "East" Direction.WEST -> "West" }
Root cause:Not understanding that when expressions must be exhaustive to return a value.
Key Takeaways
Kotlin enums represent fixed sets of constants, perfect for limited options.
The when expression lets you choose actions based on values, and can be exhaustive with enums.
Exhaustive when expressions require all enum cases to be handled or an else branch, improving safety.
Using when as an expression demands exhaustiveness to guarantee a return value.
Kotlin's compiler enforces these rules to prevent bugs from missing enum cases, making your code more reliable.

Practice

(1/5)
1. What does the Kotlin when expression require when used with an enum class?
easy
A. All enum cases must be handled to ensure exhaustive checking.
B. Only one enum case needs to be handled.
C. The when expression cannot be used with enums.
D. You must use else even if all enum cases are handled.

Solution

  1. Step 1: Understand enum and when usage

    Kotlin enums define fixed values. The when expression can check these values.
  2. Step 2: Check compiler requirements for exhaustive when

    Kotlin requires all enum cases to be handled in when to be exhaustive, avoiding missing cases.
  3. Final Answer:

    All enum cases must be handled to ensure exhaustive checking. -> Option A
  4. Quick Check:

    Exhaustive when = all enum cases handled [OK]
Hint: Remember: when with enum must cover all cases [OK]
Common Mistakes:
  • Forgetting to handle all enum values
  • Using else unnecessarily when all cases are covered
  • Assuming when can't be exhaustive with enums
2. Which of the following is the correct syntax for a when expression that exhaustively checks all values of this enum?
enum class Direction { NORTH, SOUTH, EAST, WEST }
easy
A. when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" }
B. when(dir) { Direction.NORTH, Direction.SOUTH -> "NS" }
C. when(dir) { "N" -> Direction.NORTH; "S" -> Direction.SOUTH }
D. when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S" }

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" } -> Option A
  4. Quick Check:

    All enum cases handled without else = when(dir) { Direction.NORTH -> "N"; Direction.SOUTH -> "S"; Direction.EAST -> "E"; Direction.WEST -> "W" } [OK]
Hint: List all enum values explicitly for exhaustive when [OK]
Common Mistakes:
  • Using else when all enum cases are handled
  • Missing some enum values in when
  • Using wrong types in when branches
3. What will be the output of this Kotlin code?
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))
}
medium
A. Stop
B. Go
C. Caution
D. Compilation error

Solution

  1. Step 1: Identify the enum value passed

    The function is called with Light.YELLOW.
  2. Step 2: Match enum value in when expression

    The when expression returns "Caution" for Light.YELLOW.
  3. Final Answer:

    Caution -> Option C
  4. Quick Check:

    Light.YELLOW maps to "Caution" [OK]
Hint: Match enum value to when branch to find output [OK]
Common Mistakes:
  • Confusing enum values with strings
  • Assuming else is needed for exhaustive when
  • Expecting compilation error due to missing else
4. This Kotlin code does not compile. What is the error?
enum class Status { SUCCESS, ERROR, LOADING }

fun getStatusMessage(status: Status) = when(status) {
    Status.SUCCESS -> "Done"
    Status.ERROR -> "Failed"
}
medium
A. Missing else branch in when expression
B. Not all enum cases handled in when expression
C. Incorrect enum class declaration
D. Function return type missing

Solution

  1. Step 1: Check enum cases handled in when

    Only Status.SUCCESS and Status.ERROR are handled; Status.LOADING is missing.
  2. 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.
  3. Final Answer:

    Not all enum cases handled in when expression -> Option B
  4. Quick Check:

    Missing enum case causes compilation error [OK]
Hint: Cover all enum values or add else to fix compilation [OK]
Common Mistakes:
  • Assuming else is optional when missing enum cases
  • Ignoring missing enum values in when
  • Thinking function return type causes error
5. Given this enum and function, how can you modify 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"
}
medium
A. Add an else branch to cover any missing cases.
B. Add all enum values explicitly in separate branches without combining.
C. Add a default return statement after when.
D. Keep combined branches as is; Kotlin treats it as exhaustive.

Solution

  1. 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.
  2. Step 2: Verify Kotlin's exhaustive when rules

    Kotlin considers the when exhaustive if all enum cases are explicitly covered across branches, even when grouped with commas in the same branch. No else branch is needed.
  3. Final Answer:

    Keep combined branches as is; Kotlin treats it as exhaustive. -> Option D
  4. Quick Check:

    Grouped coverage of all enum cases = exhaustive without else [OK]
Hint: Comma-grouped enum values in branches make when exhaustive [OK]
Common Mistakes:
  • Thinking combined branches don't count as exhaustive
  • Believing you must use separate branches for each enum value
  • Unnecessarily adding an else branch
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard