...

/

Non-Local and Labeled return

Non-Local and Labeled return

By default lambdas aren’t allowed to have the return keyword, even if they return a value. This is a significant difference between lambdas and anonymous functions—the latter is required to have return if returning values and it signifies only a return from the immediate lambda and not the outer calling function. In this section, we’ll look at why return is not allowed by default, how to use labeled return, and when non-local return is permitted.

return not allowed by default

return is not valid in lambdas by default, but you can use it under some special situations. This can be quite confusing if you don’t take the time to fully understand the context and the consequences. Take this topic a bit slow for the details to sink in. We’ll use a function to illustrate the concepts in this section. This function takes two parameters, an Int and a lambda, and returns Unit.

Press + to interact
fun invokeWith(n: Int, action: (Int) -> Unit) {
println("enter invokeWith $n")
action(n)
println("exit invokeWith $n")
}

Within the invokeWith() function, we pass the given Int parameter to the given lambda referenced using action(). Quite simple, nothing exciting yet.

Let’s call invokeWith() from within a caller() function and then call the caller() function.

Press + to interact
fun caller() {
(1..3).forEach { i ->
invokeWith(i) {
println("enter for $it")
if (it == 2) { return } //ERROR, return is not allowed here
println("exit for $it")
}
}
println("end of caller")
}
caller()
println("after return from caller")

The caller() function iterates over values 1 to 3 and calls ...