Skip to main content

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:

kotlin
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:

kotlin
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:

kotlin
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:

kotlin
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:

kotlin
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:

kotlin
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:

kotlin
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:

kotlin
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:

kotlin
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:

  1. Simplicity: More concise and readable than nested if-else statements
  2. Flexibility: Works with discrete values, ranges, types, and arbitrary conditions
  3. Expression capability: Can be used to assign values based on conditions
  4. Smart casting: Automatically casts variables to the appropriate type
  5. 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:

  1. Write a function that converts a numeric grade (0-100) to a letter grade (A, B, C, D, F).
  2. Create a function that takes a month number (1-12) and returns the season (Spring, Summer, Fall, Winter).
  3. Implement a simple rock-paper-scissors game using the when expression.
  4. Write a function that determines if a year is a leap year using when without arguments.

Additional Resources

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! :)