https://kotlinlang.org logo
Title
k

Karlo Lozovina

02/18/2022, 9:28 PM
Why does this code
(1..10).forEach {
            println(it)
            return@forEach
        }
print all of 10 numbers? what does even "return@forEach" mean here? It seems to work more like "continue", instead of "break"?
b

bezrukov

02/18/2022, 9:49 PM
Yes it behaves like continue because it's an early return from a lambda's scope. forEach is not a language construct, but just a function. You need to either use native for-loop (
for (it in 1..10)
) or non-labeled return. It's impossible to get break behavior with forEach (you need to use something like takeWhile)
k

Karlo Lozovina

02/18/2022, 9:56 PM
Thanks!
I'm guesing it's not the problem with forEach, this is in general impossible? To return from a lambda block?
Without having a separate predicate like takeWhile, of course
e

ephemient

02/18/2022, 9:57 PM
you can think of this as translating into
val lambda: (Int) -> Unit = forEach@{
    println(it)
    return@forEach
}
for (i in 1..10) {
    lambda(i)
}
which makes it clear why
return
can't stop the
forEach
❤️ 1
y

Youssef Shoaib [MOD]

02/19/2022, 10:38 AM
BTW, you can get break behaviour from forEach, but it requires a bit of nesting. It looks like this:
run {
    (1..10).forEach { 
        println(it)
        if(it == 5){ //Break condition 
            return@run
        }
    }
}
👍 1
k

Karlo Lozovina

02/19/2022, 1:58 PM
Thanks, it might come in handy sometimes, even though that extra nesting is a bit inelegant 🙂 ... having some kind of nonlocal return would be useful here and there ...