if, when and loops

Kotlin · Essentials · 10 min

Kotlin's expression-oriented control flow replaces the ternary operator and switch with something more powerful.

In Kotlin, if is an expression: it returns a value, so there is no ternary operator.

val max = if (a > b) a else b

when replaces switch and is also an expression:

val label = when (code) {
    200, 204 -> "ok"
    in 400..499 -> "client error"
    else -> "other"
}

Branches can match constants, several values, ranges (in), types (is String), or arbitrary conditions when when has no subject (when { x < 0 -> ... }). There is no fall-through. When used as an expression, when must be exhaustive, usually via else. Kotlin 2.2 adds guard conditions: is Shape.Circle if s.radius > 10 -> ....

Loops:

  • for (i in 1..5) (inclusive), for (i in 0 until n) or 0..<n (exclusive), for (i in 10 downTo 0 step 2).
  • for (item in list), and for ((index, item) in list.withIndex()).
  • for ((key, value) in map).
  • while and do { } while () work as in Java.

break and continue work as usual, and labels (outer@ for ... with break@outer) exit nested loops.

Many loops become simpler with collection functions (forEach, map, filter), covered later; use for when you need early exits or index-heavy logic.

Example

fun classify(code: Int): String = when (code) {
    200, 204 -> "ok"
    in 300..399 -> "redirect"
    in 400..499 -> "client error"
    else -> "other"
}

fun main() {
    val a = 3; val b = 7
    val max = if (a > b) a else b
    println(max)                                  // 7
    println(classify(204) + ", " + classify(404)) // ok, client error

    for (i in 1..3) print(i)                      // 123
    println()
    for (i in 10 downTo 0 step 5) print("$i ")    // 10 5 0
    println()
    for ((i, c) in "abc".withIndex()) print("$i$c ") // 0a 1b 2c
    println()

    outer@ for (x in 1..3) {
        for (y in 1..3) if (x * y == 4) { println("found $x*$y"); break@outer } // found 2*2
    }
}

Remember

  • if and when are expressions that return values
  • when matches values, ranges, types or conditions with no fall-through
  • 1..n is inclusive; until and ..< are exclusive
  • Labels like break@outer exit nested loops

Watch out for

  • Forgetting else in a when expression over an Int, which makes it non-exhaustive and fails to compile.

Check yourself

  1. What does for (i in 0 until 3) iterate over?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: kotlinlang.org/docs/control-flow.html