Home > OS >  Return to labels and lambda expression in kotlin
Return to labels and lambda expression in kotlin

Time:11-17

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.

  • Related