Kotlin's pattern matching capabilities have been recognized as one of its powerful features that allow for more concise and readable code. A key aspect of this is the when expression. It acts as an advanced version of the traditional switch-case operator found in many programming languages, providing more flexibility and supporting a broader set of matching criteria.
Introduction to when Expressions
The when expression in Kotlin allows developers to evaluate an expression using different matching conditions. Unlike a basic switch-case, the when expression can match various data types and features, using more expressive conditions thanks to its ability to handle ranges, types, value comparisons, and even more complex conditions seamlessly.
Basic Usage of when
Let's start with a basic example to illustrate its usage:
fun numberDescription(number: Int): String {
return when (number) {
0 -> "Zero"
1 -> "One"
else -> "Other"
}
}
In this example, the when expression checks the value of number and returns a corresponding description. The code will return "Zero" for 0, "One" for 1, and "Other" for any other integer.
Using when as a Replacement for an if-else if Chain
You can use when as a substitute for long chains of if/else if logic. This enhances code readability and maintains clarity:
fun describe(obj: Any): String = when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long Type"
!is String -> "Not a String"
else -> "Unknown Type"
}
This flexibility means designers can effortlessly compare not only values but types and conditions, encompassing unexpected branches much more neatly.
Working with Ranges
The when expression shines through its ability to check if a given value falls within a range:
fun inRange(value: Int): String = when (value) {
in 1..10 -> "In Range (1-10)"
!in 11..20 -> "Outside Range (11-20)"
else -> "Something Else"
}
This feature makes when a handy tool for reducing verbosity in scenarios where value ranges are significant decision branches.
The when Expression with Conditions
Complex conditions can be expressed naturally using when, making multi-check scenarios far more readable:
fun gradeAssessment(grade: Int): String {
return when {
grade >= 90 -> "Excellent"
grade in 75..89 -> "Good"
grade >= 50 -> "Pass"
else -> "Fail"
}
}
By omitting the expression after when, Kotlin allows conditionally structured matches, further augmenting its usability beyond simple value matching.
Using Sealed Classes and when
For enhanced type safety, Kotlin’s when is extensively powerful when used with sealed classes due to exhaustive matching abilities. Here’s a canonical implementation:
sealed class Expr
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
fun evaluate(expr: Expr): Double = when (expr) {
is Const -> expr.number
is Sum -> evaluate(expr.e1) + evaluate(expr.e2)
NotANumber -> Double.NaN
}
Sealed classes enforce exhaustive matching by ensuring all cases are checked, removing the need for an else branch and assuring superiority in reliability.
Conclusion
Combining brevity and power, Kotlin’s when expression is a cornerstone of its pattern matching capabilities, standing out for its agility in matching complex conditions succinctly and expressively. From matching simple data values and types to helping replace verbose conditional chains with clear, elegant code, when embraces the simplicity and expressivity that Kotlin developers cherish.