Control-Flow

Kotlin supports the style of control flow that you would expect in an imperative language, but it uses more modern forms of these constructs

if then else

if... then has both a statement form (no return value) and an expression form (return value).

fun main() {
  val a=5
  val b=7

  // we don't return anything, so this is a statement
  if (a > b) { 
      println("a is larger")
  } else { 
      println("b is larger")
  }

  val number = 6

  // the value from each branch is considered a return value
  // this is an expression that returns a result
  val result = 
    if (number > 0)
      "$number is positive"
    else if (number < 0)
      "$number is negative"
    else 
      "$number is zero"

  println(result)
}
Info

This is why Kotlin doesn’t have a ternary operator: if used as an expression serves the same purpose.

for in

A for in loop steps through any collection that provides an iterator. This is equivalent to the for each loop in languages like C#.

fun main() {
  val items = listOf("apple", "banana", "kiwifruit") 
  for (item in items) { 
  	println(item)
  }

  for (index in items.indices) { 
  	println("item $index is ${items[index]}")
  }

  for (c in "Kotlin") {
    print("$c ")
  }
}

Kotlin doesn’t support a C/Java style for loop. Instead we use a range collection .. that generates a sequence of values.

fun main() {
  // invalid in Kotlin	
  // for (int i=0; i < 10; ++i)

  // range provides the same funtionality
  for (i in 1..3) { 
    print(i) 
  }
  println() // space out our answers

  // descending through a range, with an optional step
  for (i in 6 downTo 0 step 2) { 
    print("$i ") 
  } 
  println()

  // we can step through character ranges too
  for (c in 'A'..'E') {
    print("$c ")
  }
  println()

  // Check if a number is within range: 
  val x = 10
  val y = 9
  if (x in 1..y+1) { 
    println("fits in range")
  }
}

while

while and do... while exist and use familiar syntax.


fun main() {
  var i = 1
  while ( i <= 10) {
    print("$i ")
    i++
  }
}

when

when replaces the switch operator of C-like languages:


fun main() {
  val x = 2
  when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> print("x is neither 1 nor 2") 
  }
}
fun main() {
    val x = 13
    val validNumbers = listOf(11,13,17,19)

    when (x) {
    	0, 1 -> print("x == 0 or x == 1")
    	in 2..10 -> print("x is in the range")
    	in validNumbers -> print("x is valid")
    	!in 10..20 -> print("x is outside the range")
    	else -> print("none of the above")
  }
}

We can also return a value from when. Here’s a modified version of this example:

fun main() {
    val x = 13
    val validNumbers = listOf(11,13,17,19)

    val response = when (x) {
        0, 1 -> "x == 0 or x == 1"
        in 2..10 -> "x is in the range"
        in validNumbers -> "x is valid"
        !in 10..20 -> "x is outside the range"
        else -> "none of the above"
    }
    println(response)
}

When is flexible. To evaluate any expression, you can move the comparison expressions into the when statement itself:

fun main() {
    val x = 13

    val response = when {
        x < 0 -> "negative"
        x >= 0 && x <= 9 -> "small"
        x >=10 -> "large"
        else -> "how do we get here?"
    }
    println(response)
}

return

Kotlin has three structural jump expressions:

  • return by default returns from the nearest enclosing function or anonymous function
  • break terminates the nearest enclosing loop
  • continue proceeds to the next step of the nearest enclosing loop