Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The when construct in Kotlin is a multi-branch conditional control flow mechanism that evaluates a target subject against a series of branch conditions sequentially until a match is found. It serves as an expression-oriented, type-safe replacement for the traditional switch statement found in C-style languages. Because when evaluates top-to-bottom, execution halts at the first successfully evaluated branch. Fall-through behavior does not occur, eliminating the need for break statements.

Expression vs. Statement

when can be utilized either as a statement or as an expression. As an Expression: When the result of the when block is assigned to a variable or returned from a function, it is treated as an expression. The compiler enforces exhaustiveness, meaning every possible value of the subject’s type must be handled. If the compiler cannot guarantee exhaustiveness, an else branch is mandatory.
val value = 3
val result: String = when (value) {
    1 -> "One"
    2 -> "Two"
    else -> "Unknown" // Mandatory else branch for exhaustiveness
}
Exhaustiveness with Sealed Classes and Enums: If the subject is an enum class, a sealed class/interface, or a Boolean, the compiler can verify exhaustiveness at compile time. If all possible cases are covered by the branches, the else branch can (and generally should) be omitted.
enum class Status { ON, OFF }

val currentStatus = Status.ON
val statusMessage: String = when (currentStatus) {
    Status.ON -> "System is running"
    Status.OFF -> "System is halted"
    // No 'else' branch required because all enum constants are covered
}
As a Statement: When used as a statement, the evaluated value is discarded. Historically, exhaustiveness was not required for statements. However, as of Kotlin 1.6, the compiler issues a warning, and as of Kotlin 1.7, it produces a hard compiler error if a when statement over an enum, sealed class, or Boolean is not exhaustive.
val numericValue = 1
when (numericValue) {
    1 -> println("One")
    2 -> println("Two")
    // else is optional here because 'numericValue' is an Int and the result is unassigned
}

Branch Condition Syntax

Kotlin permits highly flexible branch conditions, moving beyond static constants. Multiple conditions can be combined on a single branch using a comma ,, which acts as a logical OR. Constant and Arbitrary Expressions: Branches can match against literals, variables, or the evaluated result of a function call.
fun calculateValue(): Int = 5
val x = 5

when (x) {
    0, 1 -> print("x is 0 or 1")
    calculateValue() -> print("x matches the calculated value")
}
Range and Collection Checks (in / !in): Branches can evaluate whether the subject exists within a specific Iterable, array, or Range.
val y = 15
val validNumbersArray = arrayOf(11, 12, 13)

when (y) {
    in 1..10 -> print("y is in the range")
    in validNumbersArray -> print("y is in the array")
    !in 10..20 -> print("y is outside the range")
}
Type Checks and Smart Casting (is / !is): Branches can evaluate the runtime type of the subject. If an is check succeeds, the Kotlin compiler automatically smart-casts the subject to that type within the scope of the branch block.
val z: Any = "Kotlin"

when (z) {
    is String -> print(z.length) // z is smart-cast to String
    !is Int -> print("Not an integer")
}

Subject-less when

The when keyword can be declared without a subject argument. In this configuration, it acts as a direct replacement for an if-else if chain. Every branch condition must evaluate to a Boolean expression.
val a = 5
val b = 4

when {
    a % 2 != 0 -> print("a is odd")
    b % 2 == 0 -> print("b is even")
    else -> print("Fallback")
}

Variable Declaration in Subject

Kotlin allows the declaration of a variable directly within the subject parentheses of the when expression. The scope of this variable is strictly restricted to the body of the when block.
sealed class Response
class Success(val data: String) : Response()
class Failure(val error: String) : Response()

fun executeRequest(): Response = Success("Payload")

when (val response = executeRequest()) {
    is Success -> print(response.data) // 'response' is smart-cast to Success
    is Failure -> print(response.error) // 'response' is smart-cast to Failure
} // 'response' is inaccessible outside this block
Master Kotlin with Deep Grasping Methodology!Learn More