简体   繁体   中英

Break out of an anonymous function in kotlin

Created a test case to try and represent what I'm trying to do. I can't figure out how to "stop" continuing to do work inside of an anonymous function. In the example below I would like to break out of the "apple" section if the answer is correct. The code below doesn't compile because it says return@apple instead of return@banana which is the only valid option but I wrote it below to try and explain what I'm trying to achieve and better understand how to go about doing something like this.

class FunctionBreakingTest {
    @Test fun stopInMiddleOfLambda() {
        var answer = "wrong"
        doStuff apple@ {
            doStuff banana@ {
                answer = "correct"
                if (answer == "correct") {
                    return@apple
                }
                answer = "wrong"
            }

            answer = "wrong"
        }

        assertEquals("correct", answer)
    }

    private fun doStuff(foo: () -> Unit) = foo.invoke()
}

You need to make doStuff an inline function: non-local return is only supported for lambdas that are inlined.

private inline fun doStuff(foo: () -> Unit) = foo.invoke()

Then your test case passes.

Not only is return@apple illegal, just plain return is also illegal (because the non-local return requires inlining - See the answer by @hotkey, make doStuff inline and then it works)...

(Note that such non-local returns are supported only for lambda expressions passed to inline functions.)

This section of the Kotlin Documentation covers Returns at labels. Note: using anonymous functions instead of lambdas would allow you to eliminate the labels if you wanted (but, you only get local returns, and you would need to modify your code slightly).

    @Test fun stopInMiddleOfLambda() {
        var answer = "wrong"
        doStuff(fun() {
            doStuff(fun() {
                answer = "correct"
                if (answer == "correct") {
                    return
                }
                answer = "wrong"
            })
            if(answer != "wrong") {
                return
            }
            answer = "wrong"
        })
        assertEquals("correct", answer)
    }
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM