Kotlin has very nice iterating functions, like forEach
or repeat
, but I am not able to make the break
and continue
operators work with them (both local and non-local):
repeat(5) {
break
}
(1..5).forEach {
continue@forEach
}
The goal is to mimic usual loops with the functional syntax as close as it might be. It was definitely possible in some older versions of Kotlin, but I struggle to reproduce the syntax.
The problem might be a bug with labels (M12), but I think that the first example should work anyway.
It seems to me that I've read somewhere about a special trick/annotation, but I could not find any reference on the subject. Might look like the following:
public inline fun repeat(times: Int, @loop body: (Int) -> Unit) {
for (index in 0..times - 1) {
body(index)
}
}
Edit:
According to Kotlin's documentation, it is possible to simulate continue
using annotations.
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with explicit label")
}
If you want to simulate a break
, just add a run
block
fun foo() {
run {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@run // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with explicit label")
}
}
Original Answer:
Since you supply a (Int) -> Unit
, you can't break from it, since the compiler do not know that it is used in a loop.
You have few options:
Use a regular for loop:
for (index in 0 until times) {
// your code here
}
If the loop is the last code in the method
you can use return
to get out of the method (or return value
if it is not unit
method).
Use a method
Create a custom repeat method method that returns Boolean
for continuing.
public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
for (index in 0 until times) {
if (!body(index)) break
}
}