I do not quite understand what is going on here
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return // non-local return directly to the caller of foo()
print(it)
}
println("this point is unreachable")
}
fun main() {
foo()
}
The output is
12
So the integers 1
and 2
. That is because with 1
and 2
the expression if (it == 3)
evaluates to false
. But what is the return
doing here? What is returned? And to where? Is there a way to write this more verbose?
CodePudding user response:
Your function foo()
returns an implicit Unit, so when you call return
, it simply returns from foo()
immediately with the implicit Unit.
You could more verbosely write return Unit
, and you could use a regular for
loop. This is basically the same code that is being inlined by forEach
.
fun foo(): Unit {
for (it in listOf(1, 2, 3, 4, 5)) {
if (it == 3) return Unit
print(it)
}
println("this point is unreachable")
}
If instead you used return@forEach
, with or without the implicit Unit, it would be returning from the lambda, which would be the same as using continue
in a traditional for loop, since the forEach
lambda is called repeatedly, once for each iteration of the loop.
If foo()
returned something other than Unit, you would have to return that type to be able to do a non-local return:
fun foo(): Boolean {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return false
print(it)
}
println("this point is unreachable")
return true
}
You can only do non-local returns from inline function lambdas that are not crossinline
.