0
0
Kotlinprogramming~15 mins

When with multiple conditions in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - When with multiple conditions
What is it?
The 'when' expression in Kotlin is a way to check a value against multiple conditions and execute code based on which condition matches. It is similar to a switch statement in other languages but more powerful and flexible. You can combine multiple conditions in one branch using commas to check if the value matches any of them. This helps write clear and concise code when you want to handle several cases together.
Why it matters
Without the ability to check multiple conditions in one branch, you would need to write repetitive code or nested if-else statements, which can be confusing and error-prone. Using 'when' with multiple conditions makes your code easier to read and maintain, reducing bugs and improving productivity. It also helps express your intent clearly, making your programs more understandable to others.
Where it fits
Before learning 'when' with multiple conditions, you should understand basic Kotlin syntax, variables, and simple 'when' expressions with single conditions. After mastering this, you can explore more advanced control flow, such as using 'when' as an expression returning values, or combining it with smart casts and sealed classes.
Mental Model
Core Idea
A 'when' expression checks a value against several possible matches, and multiple conditions in one branch mean 'if the value matches any of these options, do this'.
Think of it like...
Imagine you have a box of colored balls and you want to group them by color. Instead of checking each color one by one, you say: if the ball is red or orange or yellow, put it in the warm colors group. This is like checking multiple conditions together in one step.
┌───────────────┐
│   when(value) │
├───────────────┤
│  condition1,  │
│  condition2,  │
│  condition3 ->│
│    action     │
├───────────────┤
│  condition4 ->│
│    action     │
└───────────────┘
Build-Up - 7 Steps
1
FoundationBasic when expression usage
🤔
Concept: Introduces the simple 'when' expression with single conditions.
val x = 2 when (x) { 1 -> println("One") 2 -> println("Two") else -> println("Other") }
Result
Two
Understanding the basic 'when' expression sets the stage for combining multiple conditions later.
2
FoundationUsing when as an expression
🤔
Concept: 'when' can return a value, not just run code blocks.
val x = 3 val result = when (x) { 1 -> "One" 2 -> "Two" else -> "Other" } println(result)
Result
Other
Knowing 'when' returns values helps write concise and functional-style code.
3
IntermediateMultiple conditions in one branch
🤔Before reading on: do you think you can check if a value is 1 or 2 in the same 'when' branch? Commit to yes or no.
Concept: You can list multiple conditions separated by commas to handle them together.
val x = 2 when (x) { 1, 2 -> println("One or Two") 3 -> println("Three") else -> println("Other") }
Result
One or Two
Knowing you can combine conditions reduces code duplication and clarifies intent.
4
IntermediateMixing multiple conditions with ranges and expressions
🤔Before reading on: can you mix multiple values and ranges in one 'when' branch? Guess yes or no.
Concept: You can combine specific values and ranges in one branch separated by commas.
val x = 5 when (x) { 1, 2, in 4..6 -> println("One, Two, or between Four and Six") else -> println("Other") }
Result
One, Two, or between Four and Six
Combining different condition types in one branch makes 'when' very flexible.
5
IntermediateUsing expressions as conditions
🤔Before reading on: do you think you can use function calls or expressions as conditions in 'when'? Commit your answer.
Concept: 'when' conditions can be any expressions that return a Boolean when used with 'when' without argument or with 'true'.
val x = 10 when { x % 2 == 0, x > 5 -> println("Even or greater than five") else -> println("Other") }
Result
Even or greater than five
Using expressions as conditions expands 'when' beyond simple value matching.
6
AdvancedSmart casts with multiple conditions
🤔Before reading on: if you check multiple types in one 'when' branch, does Kotlin smart cast the variable? Guess yes or no.
Concept: When checking multiple type conditions, Kotlin smart casts the variable inside the branch if all conditions agree on the type.
fun check(x: Any) { when (x) { is String, is CharSequence -> println("Text of length ${x.length}") else -> println("Not text") } } check("Hello")
Result
Text of length 5
Understanding smart casts with multiple conditions helps avoid casting errors and write safer code.
7
ExpertPerformance and evaluation order surprises
🤔Before reading on: do you think all conditions in a multiple-condition branch are always evaluated? Commit yes or no.
Concept: In 'when' with multiple conditions, evaluation stops at the first matching condition, but all conditions in one branch are evaluated eagerly, which can cause side effects or performance hits.
fun sideEffect(i: Int): Boolean { println("Checking $i") return i == 2 } val x = 2 when (x) { sideEffect(1), sideEffect(2) -> println("Matched") else -> println("No match") }
Result
Checking 1 Checking 2 Matched
Knowing evaluation order prevents unexpected side effects and helps optimize condition checks.
Under the Hood
The 'when' expression compiles into a series of conditional checks. When multiple conditions are in one branch separated by commas, Kotlin evaluates each condition in order until one matches. If any condition matches, the branch executes. For 'when' without argument, conditions are Boolean expressions evaluated in order. Kotlin uses smart casts inside branches when type checks are involved, allowing safe access to properties.
Why designed this way?
Kotlin's 'when' was designed to be more expressive than traditional switch statements, allowing multiple conditions per branch to reduce boilerplate and improve readability. The eager evaluation of all conditions in a branch ensures predictable behavior, even if it means some performance trade-offs. This design balances clarity, safety, and flexibility.
┌───────────────┐
│   when(value) │
├───────────────┤
│ condition1,   │
│ condition2,   │
│ condition3 -> │
│   action     │
├───────────────┤
│ condition4 -> │
│   action     │
└───────────────┘

Evaluation order:
condition1 → condition2 → condition3
If any true → execute action
Else → next branch
Myth Busters - 4 Common Misconceptions
Quick: Does Kotlin evaluate all conditions in a multi-condition 'when' branch even if the first matches? Commit yes or no.
Common Belief:Only the first matching condition in a multi-condition branch is evaluated; others are skipped.
Tap to reveal reality
Reality:All conditions in a multi-condition branch are evaluated eagerly, even if the first matches.
Why it matters:This can cause unexpected side effects or performance issues if conditions have function calls or heavy computations.
Quick: Can you use ranges and specific values together in one 'when' branch? Commit yes or no.
Common Belief:You cannot mix ranges and specific values in the same 'when' branch.
Tap to reveal reality
Reality:You can combine ranges and specific values separated by commas in one branch.
Why it matters:
Quick: Does Kotlin smart cast variables when multiple type checks are combined in one 'when' branch? Commit yes or no.
Common Belief:Kotlin does not smart cast variables if multiple type checks are combined in one branch.
Tap to reveal reality
Reality:Kotlin smart casts the variable if all type checks in the branch agree on the type.
Why it matters:Misunderstanding this leads to unnecessary casts or unsafe code.
Quick: Is 'when' with multiple conditions just syntactic sugar for multiple if-else statements? Commit yes or no.
Common Belief:'when' with multiple conditions is just a shortcut and behaves exactly like multiple if-else statements.
Tap to reveal reality
Reality:'when' expressions have distinct evaluation order and smart cast behavior that differ from if-else chains.
Why it matters:Assuming equivalence can cause subtle bugs and misunderstandings about control flow.
Expert Zone
1
When multiple conditions include function calls, all calls execute even if the first matches, which can cause side effects or performance hits.
2
Smart casts inside multi-condition branches only work if all conditions agree on the type; mixing types disables smart casts.
3
Using 'when' without an argument lets you write complex Boolean logic with multiple conditions per branch, but evaluation order and short-circuiting differ from if-else.
When NOT to use
Avoid using 'when' with multiple conditions if conditions have expensive side effects or if you need short-circuit evaluation to skip some checks. In such cases, prefer explicit if-else statements or separate checks to control evaluation order precisely.
Production Patterns
In production Kotlin code, 'when' with multiple conditions is often used for input validation, command parsing, or grouping similar cases to reduce duplication. It is combined with sealed classes and smart casts for safe and expressive control flow in domain models.
Connections
Switch statement (other languages)
'when' builds on and extends the switch statement concept.
Understanding switch helps grasp 'when', but Kotlin's multiple conditions and expression form add powerful flexibility.
Boolean logic in mathematics
'when' with multiple conditions uses logical OR to combine checks.
Knowing Boolean OR helps understand that multiple conditions mean 'if condition1 OR condition2 OR ...'.
Decision trees in machine learning
'when' expressions resemble decision nodes checking multiple conditions to decide outcomes.
Seeing 'when' as a decision tree helps appreciate its role in branching logic and efficient decision making.
Common Pitfalls
#1Unexpected side effects from all conditions evaluating
Wrong approach:fun check(x: Int): Boolean { println("Checking $x") return x == 2 } val y = 2 when (y) { check(1), check(2) -> println("Matched") else -> println("No match") }
Correct approach:val y = 2 if (check(1) || check(2)) { println("Matched") } else { println("No match") }
Root cause:Misunderstanding that all conditions in a 'when' branch are evaluated eagerly, unlike short-circuiting in if-else.
#2Mixing incompatible types disables smart casts
Wrong approach:fun test(x: Any) { when (x) { is String, is Int -> println(x.length) // Error: Int has no length else -> println("Other") } }
Correct approach:fun test(x: Any) { when (x) { is String -> println(x.length) is Int -> println(x) // handle Int separately else -> println("Other") } }
Root cause:Assuming smart casts work when multiple types are checked together in one branch.
#3Assuming 'when' branches short-circuit conditions
Wrong approach:val x = 2 when (x) { expensiveCheck1(), expensiveCheck2() -> println("Matched") else -> println("No match") }
Correct approach:val x = 2 if (expensiveCheck1() || expensiveCheck2()) { println("Matched") } else { println("No match") }
Root cause:Confusing 'when' multiple conditions with if-else short-circuit evaluation.
Key Takeaways
'when' with multiple conditions lets you check if a value matches any of several options in one branch, making code concise and clear.
All conditions in a multi-condition branch are evaluated eagerly, which can cause side effects or performance issues if conditions have function calls.
You can mix specific values, ranges, and expressions as conditions in one 'when' branch for great flexibility.
Kotlin smart casts variables inside 'when' branches if all type checks agree, enabling safe and concise code.
Understanding evaluation order and smart cast behavior in 'when' prevents subtle bugs and helps write efficient, readable Kotlin code.