When

when is distinctive. when is powerful. when is used a lot in Kotlin programming. And when is somewhat different than what you’ll see in many other programming languages.

What We Do Elsewhere

The closest analogy to when in Java is the switch statement:

switch(foo) {
  case 1:
    // do something
    break;
  case 2:
    // do something else
    break;
  default:
    // like, whatever
}

Here, depending on the value of foo, we evaluate one set of statements that follows the matching case (or the default statements, if there are no matches).

JavaScript also has a switch, with the same syntax as Java.

Ruby uses case, and it is the closest of the three in terms of matching the power of when:

case foo
  when 1
    # do something
  when 2
    # do something else
  else
    # like, whatever
end

The Basic Use of when

The most commonly-seen form of when looks like a Java/JavaScript switch or a Ruby case, where you supply a value for comparison and set up different branch conditions to test against that value:

  val i = 3

  when (i) {
    1 -> println("something")
    2 -> println("something else")
    else -> println("and now for something completely different")
  }

Each branch has a value (1 and 2) that is compared to the input (i). The first match has its statement or block evaluated, and everything else is skipped. If there are no matches, the else statement or block is executed. The -> separates the branch comparison from the stuff that should be executed if that branch comparison is met.

In this case, the output is:

and now for something completely different

While that snippet uses Int values for comparison, that is not a requirement — anything that can be compared using equality (==) can be used:

  val thingy = "foo"

  when (thingy) {
    "foo" -> println("something")
    "bar" -> println("something else")
    else -> println("and now for something completely different")
  }

However, you cannot mix types, unless == happens to work to compare them. This, for example, fails with a compile error, pointing out that Int and String are incompatible types:

val thingy = "foo"

when (thingy) {
  "foo" -> println("something")
  2 -> println("something else")
  else -> println("and now for something completely different")
}

Using when Instead Of else if

The when syntax from the preceding section is fairly similar to switch and case. However, when has many more options.

One option is to skip the parameter to the when. In that case, each branch has its own Boolean expression, and the first that evaluates to true is used. This results in a more direct analogue to if/else if/else:

  val i = 3

  when {
    i > 10 -> println("something")
    i > 2 -> println("something else")
    else -> println("and now for something completely different")
  }

Consolidating Multiple Branches

If you have a few values that all should route to the same branch, you can use a comma-delimited list instead of a single value for the branch comparison against the value supplied to when:

  val thingy = "foo"

  when (thingy) {
    "foo", "goo" -> println("something")
    "bar", "baz", "frobozz" -> println("something else")
    else -> println("and now for something completely different")
  }

Kotlin will compare each of the comma-delimited values and if any of them match, that branch is used.

For numbers, you can use .. syntax and in to set up a “range” and test against it:

  val i = 3

  when (i) {
    in 3..10 -> println("something")
    in 1..2 -> println("something else")
    else -> println("and now for something completely different")
  }

However, these simplifications only work when you supply a value to when (when(thingy)), as opposed to leaving when empty and using boolean expressions for the branches.

Expressions As Branch Conditions

The value for comparison does not need to be a constant — any expression will also work:

  val thingy = "bar"
  val otherThingy = "BAR"

  when (thingy) {
    "foo", "goo" -> println("something")
    otherThingy.toLowerCase() -> println("something else")
    else -> println("and now for something completely different")
  }

Here, the second branch compares thingy to otherThingy.toLowerCase() — in this case, they are equal, and so that branch is used.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.