There are two options of the loop function:
-
fun loop(body: suspend LoopScope<Unit>.() -> Unit): Unit
-
fun <T> loopWithResult(@BuilderInference body: suspend LoopScope<T>.() -> Unit): T
loopWithResult
supports a parameterized break
function whose parameter is then returned.
continue
and break
analogues are defined inside LoopScope
interface:
@RestrictsSuspension
interface LoopScope<T> {
suspend fun breakLoop(result: T): Nothing
suspend fun continueLoop(): Nothing
}
suspend fun LoopScope<Unit>.breakLoop(): Nothing = breakLoop(Unit)
The solution does not depend on the exceptions, so it is safe to wrap break
s and continue
s with runCatching
and try
.
The solution is also not recursive, so number of iterations is not limited by the stack size.
var cur = 0
loop {
cur++
if (cur == 2) continueLoop()
if (cur == 5) breakLoop()
println(cur)
}
Output:
1
3
4