Kotlin When Expression
The when
expression is one of Kotlin's most powerful control flow features. Think of it as an enhanced and more flexible version of the traditional switch
statement found in other programming languages. The when
expression allows you to check a value against multiple conditions, making your code more readable and concise.
Introduction to the When Expression
In many programming scenarios, you need to execute different code blocks based on different values of a variable. While if-else
chains can handle this, they can become lengthy and hard to read. Kotlin's when
expression provides a more elegant solution for such scenarios.
Basic Syntax
Here's the basic syntax of the when
expression:
when (value) {
condition1 -> { /* code block */ }
condition2 -> { /* code block */ }
condition3, condition4 -> { /* code block for multiple conditions */ }
else -> { /* default code block */ }
}
If a code block consists of a single statement, the curly braces are optional:
when (value) {
condition1 -> statement1
condition2 -> statement2
else -> defaultStatement
}
Simple When Expression Examples
Let's start with a basic example where we check the value of a day and print a message:
fun main() {
val day = 3
when (day) {
1 -> println("Monday")
2 -> println("Tuesday")
3 -> println("Wednesday")
4 -> println("Thursday")
5 -> println("Friday")
6 -> println("Saturday")
7 -> println("Sunday")
else -> println("Invalid day")
}
}
Output:
Wednesday
In this example, since day
is 3
, the when
expression executes the code associated with the condition 3
, printing "Wednesday".
Using When as an Expression
One of the most powerful features of Kotlin's when
is that it can be used as an expression, meaning it can return a value:
fun main() {
val day = 2
val dayType = when (day) {
1, 2, 3, 4, 5 -> "Weekday"
6, 7 -> "Weekend"
else -> "Invalid day"
}
println("Day $day is a $dayType")
}
Output:
Day 2 is a Weekday
Here, the when
expression evaluates and assigns either "Weekday", "Weekend", or "Invalid day" to the dayType
variable.
When Without an Argument
Kotlin allows using when
without providing an argument. In this case, each branch condition is a boolean expression:
fun main() {
val number = 75
when {
number < 0 -> println("Negative number")
number in 0..9 -> println("Single digit")
number in 10..99 -> println("Double digit")
number >= 100 -> println("Three or more digits")
}
}
Output:
Double digit
This format is especially useful when you need to check multiple unrelated conditions.
Using When with Ranges and Collections
Kotlin's when
expression can also check if a value falls within a range or exists in a collection:
fun main() {
val number = 42
when (number) {
in 1..10 -> println("Number is between 1 and 10")
in 11..50 -> println("Number is between 11 and 50")
!in 1..100 -> println("Number is not between 1 and 100")
else -> println("Number is between 51 and 100")
}
val validNumbers = listOf(10, 20, 30, 40, 50)
when (number) {
in validNumbers -> println("$number is a valid number")
else -> println("$number is not a valid number")
}
}
Output:
Number is between 11 and 50
42 is not a valid number
Using When with Smart Casts
The when
expression works seamlessly with Kotlin's smart casts, allowing you to check an object's type and process it accordingly:
fun describe(obj: Any): String {
return when (obj) {
is String -> "The string has length ${obj.length}"
is Int -> "The integer value is $obj"
is Boolean -> "The boolean value is $obj"
is List<*> -> "The list has ${obj.size} elements"
else -> "Unknown object type"
}
}
fun main() {
println(describe("Hello"))
println(describe(42))
println(describe(true))
println(describe(listOf(1, 2, 3)))
println(describe(3.14))
}
Output:
The string has length 5
The integer value is 42
The boolean value is true
The list has 3 elements
Unknown object type
Real-World Example: Simple Calculator
Let's build a simple calculator using the when
expression:
fun calculate(num1: Double, num2: Double, operator: Char): Double {
return when (operator) {
'+' -> num1 + num2
'-' -> num1 - num2
'*' -> num1 * num2
'/' -> {
if (num2 == 0.0) {
throw IllegalArgumentException("Division by zero is not allowed")
}
num1 / num2
}
'%' -> num1 % num2
else -> throw IllegalArgumentException("Unknown operator: $operator")
}
}
fun main() {
try {
println("5 + 3 = ${calculate(5.0, 3.0, '+')}")
println("5 - 3 = ${calculate(5.0, 3.0, '-')}")
println("5 * 3 = ${calculate(5.0, 3.0, '*')}")
println("5 / 3 = ${calculate(5.0, 3.0, '/')}")
println("5 % 3 = ${calculate(5.0, 3.0, '%')}")
// This will throw an exception
// println("5 $ 3 = ${calculate(5.0, 3.0, '$')}")
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
}
Output:
5 + 3 = 8.0
5 - 3 = 2.0
5 * 3 = 15.0
5 / 3 = 1.6666666666666667
5 % 3 = 2.0
Another Practical Example: HTTP Status Codes
Let's implement a function that returns messages for different HTTP status codes:
fun getHttpStatusMessage(statusCode: Int): String {
return when (statusCode) {
in 100..199 -> "Informational Response"
in 200..299 -> "Success"
in 300..399 -> "Redirection"
in 400..499 -> "Client Error"
in 500..599 -> "Server Error"
else -> "Unknown Status Code"
}
}
fun main() {
println("Status 200: ${getHttpStatusMessage(200)}")
println("Status 404: ${getHttpStatusMessage(404)}")
println("Status 500: ${getHttpStatusMessage(500)}")
println("Status 302: ${getHttpStatusMessage(302)}")
println("Status 600: ${getHttpStatusMessage(600)}")
}
Output:
Status 200: Success
Status 404: Client Error
Status 500: Server Error
Status 302: Redirection
Status 600: Unknown Status Code
Summary
Kotlin's when
expression is a versatile and powerful control flow mechanism that offers:
- Simplicity: More concise and readable than nested if-else statements
- Flexibility: Works with discrete values, ranges, types, and arbitrary conditions
- Expression capability: Can be used to assign values based on conditions
- Smart casting: Automatically casts variables to the appropriate type
- Multiple values per branch: Can group multiple conditions with the same outcome
By mastering the when
expression, you'll be able to write cleaner, more maintainable Kotlin code for a variety of conditional logic scenarios.
Exercises
To practice using the when
expression, try these exercises:
- Write a function that converts a numeric grade (0-100) to a letter grade (A, B, C, D, F).
- Create a function that takes a month number (1-12) and returns the season (Spring, Summer, Fall, Winter).
- Implement a simple rock-paper-scissors game using the
when
expression. - Write a function that determines if a year is a leap year using
when
without arguments.
Additional Resources
- Kotlin Official Documentation on When Expression
- Kotlin By Example: When Expression
- Control Flow in Kotlin
Remember that the when
expression is most effective when you need to check a single value against multiple conditions or when you need to perform type checking on a variable. For simple binary conditions, an if-else
statement might still be more appropriate.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)