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.

In Kotlin, if is an expression that evaluates a boolean condition and returns a value based on the executed branch. Because it yields a value, Kotlin does not possess a traditional ternary operator (condition ? then : else); the if expression natively fulfills this role.

Syntax Mechanics

The if construct functions either as a standard control flow statement or as an expression assigned to a variable. As a Statement: When used as a statement, the if construct does not require an else branch. It directs control flow without returning a value.
fun evaluateStatement() {
    val a = 10
    val b = 20

    if (a > b) {
        println("a is greater")
    } else if (a == b) {
        println("a equals b")
    } else {
        println("b is greater")
    }
}
As an Expression: When used as an expression, the if construct evaluates to a value.
fun evaluateExpression() {
    val a = 10
    val b = 20
    
    val max = if (a > b) a else b
}

Evaluation Rules

When utilizing if as an expression, specific compiler rules apply:
  1. Exhaustiveness: The expression must be exhaustive. An else branch is strictly mandatory so the compiler can guarantee a value is returned regardless of the condition’s outcome.
  2. Block Evaluation: If a branch is enclosed in a block { ... }, the value of that branch is determined by the last expression within the block. Preceding statements are executed for their side effects.
  3. Type Resolution: The compiler determines the return type of the if expression by finding the least upper bound (common supertype) of the types returned by all branches.

Block Expression Syntax

When branches require multiple operations, the final expression in the block dictates the return value:
fun performOperation() { 
    println("Executing side effect...") 
}

fun calculateValue(): Int {
    return 5
}

fun evaluateBlock() {
    val condition = true
    
    val result = if (condition) {
        performOperation()
        val intermediate = calculateValue()
        intermediate * 2 // This is the evaluated return value of the 'if' branch
    } else {
        0 // This is the evaluated return value of the 'else' branch
    }
}

Type Inference Behavior

If the branches of an if expression return different types, the Kotlin compiler infers the closest common supertype. If the if is used as a statement (not assigned or returned), its evaluated type is implicitly Unit.
fun evaluateTypeInference() {
    val condition = true
    
    // Branch 1 returns Int, Branch 2 returns String.
    // The compiler infers the type of 'mixedResult' as Any.
    val mixedResult = if (condition) {
        42 
    } else {
        "Fallback" 
    }
}

Smart Casting

A critical semantic feature of Kotlin’s if construct is its integration with the compiler’s control flow analysis to enable Smart Casting. When an if condition checks a variable’s type using the is operator or verifies nullability (!= null), the compiler automatically casts the variable to the target type within the lexical scope of the corresponding branch.
fun evaluateSmartCast(obj: Any, nullableString: String?) {
    // Smart casting via type checking
    if (obj is String) {
        // 'obj' is automatically smart-cast to String in this branch
        println(obj.uppercase()) 
    }

    // Smart casting via nullability checking
    if (nullableString != null) {
        // 'nullableString' is automatically smart-cast to a non-nullable String
        println(nullableString.length)
    }
}
Master Kotlin with Deep Grasping Methodology!Learn More