8

I am converting a large project to Kotlin. There have been numerous challenges. Me learning the new patterns of Kotlin is one of them. Hopefully there is a pattern I can use to resolve this one.

Here is the code I am attempting to achieve. But, continue and break are not valid in a when statement.

while (!mStopped && c.moveToNext()) {

    val itemType = c.getInt()
    when (itemType) {
        1, 2 -> {
            doSomething()
            if (condition)
                continue
            doSomethingElse()
        }
    }
    doTheLastStuff()
}

This is a very cut-down version of the code. The original java code had 100's of lines inside the switch statements, and lots of continue's and break's.

What I am trying to achieve is to continue execution back at the while statement. What is the pattern for doing this in Kotlin

Brian Donovan-Smith
  • 392
  • 1
  • 5
  • 13
  • After that, maybe see if you can turn the loop into a tail recursive function, which can be optimized with Kotlin's tailrec "annotation". – Jacob Zimmerman Jan 10 '16 at 19:15
  • 3
    (Note: This is not a duplicate of the other. The other is about functional loops, this is about non-functional loops. I flagged for moderator intervention to "un-mark this as a dupe, because it is not") – Jayson Minard Jan 11 '16 at 12:17

2 Answers2

7

You can use labels to continue/break the loop i.e:

myLoop@ while (!mStopped && c.hasNext()) {

    val itemType = c.next()
    when (itemType) {
        1, 2 -> {
            doSomething()
            if (condition())
                continue@myLoop
            doSomethingElse()
        }
    }
    doTheLastStuff()
}

Here's is a relevant excerpt from documentation:

Any expression in Kotlin may be marked with a label. Labels have the form of an identifier followed by the @ sign, for example: abc@, fooBar@ are valid labels(...) A break qualified with a label jumps to the execution point right after the loop marked with that label. A continue proceeds to the next iteration of that loop.

miensol
  • 39,733
  • 7
  • 116
  • 112
6

The issue here is that break and continue have a special meaning inside a when statement, namely breaking and continuing the when itself, not the surrounding loop. For now (kotlin 1.0) the syntax is not decided yet, so the feature does not work, despite the keywords being reserved.

To solve this, use labels https://kotlinlang.org/docs/reference/returns.html#break-and-continue-labels:

loop@ while (...) {
    when (itemType) {
        1 -> continue@loop
        else -> break@loop
    }
}
Alexander Udalov
  • 31,429
  • 6
  • 80
  • 66
voddan
  • 31,956
  • 8
  • 77
  • 87