Introduction to When Expression in Kotlin Programming Language
The When Expression in Kotlin Programming Language is one of the most powerful control flow structures. It provides a more concise and readable way to handle multiple conditions
compared to traditionalif-else
chains. In many ways, it acts like a modernized version of the switch
statement from other programming languages like Java or C, but with far more flexibility and functionality.
In this article, we’ll explore how the when
expression works in Kotlin, its various use cases, and how it can simplify code, especially when dealing with multiple branches of logic.
Understanding when
Expression
The when
expression in Kotlin evaluates a value or a condition and matches it against several possible cases. Once it finds a match, it executes the corresponding block of code. Unlike a switch
statement, when
doesn’t need a break after each case since it automatically terminates after finding a match.
Basic Syntax of when
when (value) {
case1 -> { // code for case1 }
case2 -> { // code for case2 }
else -> { // code if no cases match }
}
Example of a Simple when
Expression
val dayOfWeek = 3
val day = when (dayOfWeek) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
6 -> "Saturday"
7 -> "Sunday"
else -> "Invalid day"
}
println(day) // Output: Wednesday
In this example, the variable dayOfWeek
is compared against each possible value (1 through 7), and the corresponding day is returned. The else
branch acts as a fallback, ensuring that even if none of the cases match, the program won’t fail.
when
as an Expression
In Kotlin, when
is not just a statement but an expression. This means that it can return a value, which can be assigned to variables. This is one of the features that makes Kotlin’s when
much more powerful than the traditional switch
statement.
Example
val number = 10
val result = when (number) {
in 1..10 -> "Number is between 1 and 10"
in 11..20 -> "Number is between 11 and 20"
else -> "Number is outside the range"
}
println(result) // Output: Number is between 1 and 10
Here, the when
expression evaluates the value of number
and returns a string based on which range the number falls into. This string is then stored in the result
variable.
when
Without an Argument
One unique feature of Kotlin’s when
expression is that it can be used without providing an argument. In this form, it behaves like a series of if-else
checks, which is useful when each branch evaluates a different condition.
Example
val age = 25
when {
age < 18 -> println("You are a minor.")
age >= 18 && age < 65 -> println("You are an adult.")
else -> println("You are a senior citizen.")
}
In this example, there is no value being passed into when
. Instead, each branch evaluates its own boolean condition. This approach provides flexibility when you need to check multiple independent conditions.
Using Multiple Conditions in a Single Branch
Kotlin’s when
expression allows you to group multiple conditions into a single branch, making it easier to handle multiple cases that should execute the same block of code.
Example
val letter = 'A'
when (letter) {
'A', 'E', 'I', 'O', 'U' -> println("The letter is a vowel.")
else -> println("The letter is a consonant.")
}
Here, if the value of letter
is any of the vowels (‘A’, ‘E’, ‘I’, ‘O’, ‘U’), the first branch executes. Otherwise, the else
branch handles consonants.
Checking Types with when
Another great feature of Kotlin’s when
expression is that it can be used to check the type of a variable. This is particularly useful in scenarios where a variable can hold different types of data, and you need to execute code based on its type.
Example
fun identifyType(input: Any) {
when (input) {
is String -> println("Input is a String")
is Int -> println("Input is an Integer")
is Boolean -> println("Input is a Boolean")
else -> println("Unknown type")
}
}
identifyType(123) // Output: Input is an Integer
identifyType("Hello") // Output: Input is a String
identifyType(true) // Output: Input is a Boolean
In this example, the when
expression is used to identify the type of the input
variable, which can hold any type (Any
). Based on the type, the corresponding block of code is executed.
Using Ranges in when
Kotlin allows you to use ranges inside when
expressions, which can simplify code when dealing with numeric values that fall within a certain range.
Example
val score = 85
when (score) {
in 90..100 -> println("Excellent")
in 75..89 -> println("Good")
in 50..74 -> println("Average")
else -> println("Poor")
}
Here, the when
expression checks if score
falls within a specific range and prints an appropriate message.
Smart Casts in when
Kotlin’s when
expression benefits from smart casting. When you check the type of a variable with is
, the variable is automatically cast to that type within the corresponding block, eliminating the need for explicit casting.
Example
fun processInput(input: Any) {
when (input) {
is String -> println("String length: ${input.length}") // Smart cast to String
is Int -> println("Square of number: ${input * input}") // Smart cast to Int
else -> println("Unsupported type")
}
}
processInput("Kotlin") // Output: String length: 6
processInput(7) // Output: Square of number: 49
In this example, once Kotlin confirms that input
is a String
or Int
, it automatically casts it to that type, allowing you to use type-specific properties and methods.
Using when
for Enum Classes
Enums are a set of predefined constants in Kotlin. The when
expression is often used to handle enum values, making the code concise and clean.
Example
enum class Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
fun printDayType(day: Day) {
when (day) {
Day.SATURDAY, Day.SUNDAY -> println("It's a weekend!")
else -> println("It's a weekday.")
}
}
printDayType(Day.MONDAY) // Output: It's a weekday.
Here, the when
expression checks the value of the day
enum and prints whether it’s a weekend or a weekday.
Exhaustiveness in when
with Enums and Sealed Classes
One of the great benefits of using when
with enums and sealed classes is that the compiler enforces exhaustiveness. This means you must handle all possible cases; otherwise, the compiler will throw an error. This makes the code more reliable and reduces the risk of runtime errors.
Example with Sealed Class
sealed class Shape {
class Circle(val radius: Double) : Shape()
class Rectangle(val width: Double, val height: Double) : Shape()
}
fun getShapeArea(shape: Shape): Double {
return when (shape) {
is Shape.Circle -> Math.PI * shape.radius * shape.radius
is Shape.Rectangle -> shape.width * shape.height
}
}
Since Shape
is a sealed class, the when
expression must handle all possible types (Circle
and Rectangle
). If a new type is added to the sealed class, the compiler will require you to update the when
expression.
Advantages of When Expression in Kotlin Programming Language
The when
expression is a key feature in Kotlin that provides numerous advantages, making it a preferred choice for conditional logic. Below are the main benefits of using when
in your Kotlin programs.
1. Conciseness and Readability
The when
expression allows for more concise code compared to traditional if-else
chains. It reduces boilerplate and improves readability, making it easier for developers to follow the program’s flow.
2. Versatile Conditions
With when
, you can evaluate a wide range of conditions. It supports checks against types, ranges, and even complex expressions, providing flexibility in how you structure your conditional logic.
3. Smart Casting
Kotlin’s smart casting feature works effectively within when
expressions. After checking a type, the compiler automatically casts it, reducing the need for explicit casting and enhancing code clarity.
4. Returning Values
The when
expression can return values, allowing you to assign the result directly to a variable or use it as an argument in a function. This capability promotes a more functional programming style.
5. Enhanced Null Safety
Kotlin’s null safety features can be effectively utilized in when
expressions. By allowing for easy handling of nullable types, when
helps prevent null pointer exceptions and makes your code more robust.
6. Handling Multiple Cases
You can group multiple conditions under a single case in a when
expression. This reduces redundancy and improves code organization, especially when similar cases share common logic.
7. Default Case Handling
The else
clause in a when
expression serves as a default case for any unmatched conditions. This enhances the robustness of your code by ensuring it can handle unexpected input gracefully.
8. Advanced Pattern Matching
Kotlin’s when
expression supports advanced pattern matching, allowing for destructuring of objects and performing complex evaluations. This feature simplifies working with data classes and sealed classes.
Disadvantages of When Expression in Kotlin Programming Language
While the when
expression in Kotlin offers numerous advantages, it also comes with some disadvantages that developers should consider. Below are the key drawbacks associated with using when
.
1. Complexity with Extensive Cases
As the number of cases within a when
expression increases, the logic can become complex and harder to manage. This can lead to difficulties in understanding the overall flow of the code, particularly for those unfamiliar with the specific conditions being evaluated.
2. Performance Concerns
In some scenarios, especially with a large number of branches, the performance of a when
expression may be less optimal compared to traditional if-else
statements. The overhead of evaluating multiple conditions can impact performance, particularly in performance-critical applications.
3. Limited to Single Value Comparisons
The when
expression primarily operates based on a single subject value. While it can handle various conditions, it may not be as effective for scenarios requiring more complex logical evaluations involving multiple variables.
4. Verbose Syntax for Complex Logic
When used for complex logic that requires extensive branching or conditional checks, the syntax of a when
expression can become verbose and cumbersome. This can detract from the clarity that when
is meant to provide.
5. Lack of Early Exit
Unlike some other control structures, when
does not support early exits, such as return
or break
statements, in the way that if
statements can be used. This can limit its use in certain scenarios where an immediate exit from the enclosing scope is desired.
6. Potential for Unmatched Cases
If not all possible cases are handled (especially in the absence of an else
clause), it can lead to runtime exceptions. This requires developers to be diligent in ensuring that all scenarios are appropriately covered, adding to the maintenance burden.
7. Readability Issues in Nested Structures
When nesting when
expressions or combining them with other control structures, the overall readability of the code can suffer. This can make it challenging for other developers to follow the logic and may lead to increased chances of errors.
Discover more from PiEmbSysTech
Subscribe to get the latest posts sent to your email.