Table of Contents
In Kotlin while and for block, break and continue can be used, but they can’t be used in forEach or repeat block.
Environment
- Kotlin 1.3.11
First, I will introdyce easy coping strategy when we want to use break or continue in forEach or repeat.
Easy Coping Strategy
Both forEach and repeat can be replaced with for. If we rewrite with for, then we can use break and continue.
| Before | After | |
|---|---|---|
forEach |
something.forEach |
for (it in something) |
repeat |
repeat (time) |
for (it in time) |
Why break or continue can’t be used
(Directly speaking, Kotlin is built as it is.) while and for are completely different from forEach and repeat.
whileandforare syntax defined as Kotlin.forEachandrepeatare functions
They are very similar in writing, but while and for are syntax, in which break and continue can be used. On the other hand, forEach and repeat are higher order functions defined in Kotlin standard library.
|
1 2 3 |
releat (3) { // this is function } |
So, { ... } is function for forEach and repeat.
It is weird that break and continue appear in function, isn’t it? break and continue can’t be used.
Another way to control iteration
To escape the block in higher-order functions such as forEach and repeat, use return. It is natural that return finish it, because it is a function.
But, using return as it is, the caller function will be finished.
|
1 2 3 4 5 6 7 |
fun something() { listOf(1, 2, 3).forEach { println(it) return // finish something function } println("finish") } |
Use label to control it easily.
continue-like control
Using lambda
return@labelOfLambda is continue-like control in lambda.
|
1 2 3 4 5 6 7 8 |
fun something() { listOf(1, 2, 3).forEach { println(it) return@forEach // go back to the top of forEach block println(it) } println("finished") } |
The label can be named by ourselvs, such as labelName@{ ... }.
If double forEach are used
If forEach is used in double, name the label by yourself. In the following code, continue works for outer forEach loop.
|
1 2 3 4 5 6 7 8 9 10 |
fun something() { listOf(1, 2, 3).forEach outer@{ a -> listOf(4, 5, 6).forEach { b -> print(a) return@outer println(b) } } println("finished") } |
Using anonymous function
If you change lambda to anonymous function, you can simply use return for continuation.
|
1 2 3 4 5 6 7 |
fun something() { listOf(1, 2, 3).forEach(fun(value: Int) { println(value) return // go back to the top of forEach block println(it) }) } |
break-like control
Use label, but you need outer scope function.
Using lambda
Surround with run, and write return@run.
|
1 2 3 4 5 6 7 8 9 10 |
fun something() { run { listOf(1, 2, 3).forEach { println(it) return@run // finish the loop println(it) } } println("finished") } |
As you can see, lambda is built without consideration of break.
Using anonymous function
Use label like when we use lambda.
|
1 2 3 4 5 6 7 8 9 |
fun something() { var breakFlag = false listOf(1, 2, 3).forEach(fun(value) { println(value) return@run // finish the loop println(value) }); println("finished") } |
Summary of break and continue
| break | continue | |
| lambda | Scope function and label | label |
|---|---|---|
| anonymous function | return |


