Kotlin Switch: Implementing Switch-Case Functionality with the `when` Expression
Kotlin does not provide a traditional switch keyword; instead, it offers the powerful when expression, which serves as a type-safe replacement with support for exhaustive checking, smart casts, and flexible pattern matching.
If you are searching for kotlin switch functionality, you will find that the JetBrains/kotlin repository implements control flow through the versatile when construct. This expression functions as both a statement for side effects and an expression that returns values, while integrating deeply with Kotlin's type system to provide compile-time safety.
Understanding the Kotlin Switch Alternative
Unlike C-style languages that rely on the switch keyword, Kotlin's when expression provides a more robust solution for multi-way branching. As implemented in the compiler's frontend and IR pipelines, when can operate as an expression that yields a value or as a statement that performs side effects.
The construct supports two distinct forms: one with an explicit subject (when (x) { ... }) and one without (when { ... }), giving developers flexibility in how they structure conditional logic.
Kotlin Switch Syntax: Subject and Condition Forms
Subject-Based when (Traditional Switch Style)
When you provide a subject, when compares the subject's value against branch conditions sequentially. This form closely resembles traditional switch-case statements but eliminates fall-through behavior.
val day = 3
when (day) {
1 -> println("Monday")
2 -> println("Tuesday")
3 -> println("Wednesday")
else -> println("Another day")
}
Subjectless when (Flexible Boolean Conditions)
Omitting the subject allows you to write arbitrary boolean expressions as branch conditions. This is particularly useful for range checks or complex condition combinations that would be cumbersome in a traditional switch statement.
val score = 87
val grade = when {
score >= 90 -> "A"
score >= 80 -> "B"
score >= 70 -> "C"
else -> "F"
}
println("Grade: $grade")
Kotlin Switch Branch Types and Pattern Matching
The when expression supports multiple branch types, enabling sophisticated pattern matching beyond simple value equality.
Value Matching and Collections
Branches can match single values, multiple values combined with commas, or check membership in collections using the in and !in operators.
val x = 10
when (x) {
0, 1 -> println("Binary digit")
in 2..9 -> println("Single digit")
!in 0..99 -> println("Double digit or more")
else -> println("Other")
}
Type Checking with Smart Casts
Using the is and !is operators, when branches can check types and automatically cast the subject to that type within the branch. This smart cast functionality is implemented in the compiler's FIR and IR layers, specifically in WhenEntry.kt and WhenBranchOptimiserLowering.kt.
fun describe(value: Any) = when (value) {
is String -> "String of length ${value.length}"
is Int -> "Integer $value"
else -> "Unknown type"
}
println(describe("Kotlin"))
Exhaustiveness Checking for Enums and Sealed Classes
When the subject is an enum or sealed type, the Kotlin compiler verifies that all possible cases are covered. This exhaustiveness checking is handled by WhenChecker.kt in the frontend, with diagnostic reporting centralized in WhenMissingCase.kt. If a branch is missing, the compiler emits a diagnostic error, ensuring type-safe control flow without requiring an else branch.
sealed class Result
data class Success(val data: String) : Result()
object Failure : Result()
fun handle(result: Result) = when (result) {
is Success -> "Got ${result.data}"
Failure -> "Operation failed"
} // No 'else' needed – compiler verifies exhaustiveness
Kotlin Switch Implementation in the Compiler
The kotlin switch functionality is deeply integrated into the compiler's architecture. In the FIR (Frontend Intermediate Representation) layer, WhenEntry.kt represents individual branches of a when expression. During IR (Intermediate Representation) lowering, WhenBranchOptimiserLowering.kt optimizes branch conditions and eliminates dead code.
The exhaustiveness analysis that makes when safer than traditional switch statements is implemented in WhenChecker.kt, which traverses the control flow graph to ensure all possible values of sealed classes and enums are handled. Diagnostic reporting for missing cases is centralized in WhenMissingCase.kt.
Summary
- Kotlin replaces the traditional switch statement with the more powerful
whenexpression. whenfunctions as both an expression (returning values) and a statement (executing side effects).- The construct supports subject-based and subjectless forms for flexible condition checking.
- Advanced features include smart casts with
ischecks, collection membership within/!in, and exhaustiveness checking for sealed classes and enums. - Compiler implementation resides in
WhenChecker.kt,WhenMissingCase.kt,WhenEntry.kt, andWhenBranchOptimiserLowering.ktwithin the JetBrains/kotlin repository.
Frequently Asked Questions
Does Kotlin have a traditional switch statement?
No, Kotlin does not include a switch keyword. Instead, it provides the when expression, which offers equivalent functionality with additional features like smart casts, exhaustiveness checking, and the ability to handle arbitrary boolean conditions.
Can Kotlin when be used as an expression?
Yes, when can function as an expression that returns a value, allowing you to assign the result directly to a variable. It can also be used as a statement when you only need to execute side effects like printing output.
How does Kotlin enforce exhaustive when expressions?
The Kotlin compiler enforces exhaustiveness through WhenChecker.kt in the frontend. When the subject of a when expression is a sealed class or enum, the compiler verifies that all possible cases are covered and emits a diagnostic error via WhenMissingCase.kt if any branch is missing.
Is it possible to use when without a subject in Kotlin?
Yes, you can omit the subject to create a subjectless when expression. This form allows you to write arbitrary boolean expressions as branch conditions, making it ideal for range checks or complex logical combinations that would be difficult to express with a traditional switch statement.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →