Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
89 views
in Technique[技术] by (71.8m points)

android - Kotlin: Whats does "return@" mean?

I'm using RxJava in one of my projects, I converted one of my classes to Kotlin using the Android Studio plugin and in one of map flatMap lambda (Func1 in java), intermediates returns looks like the following @Func1.

I have no idea what this means.

something.flatMap(Func1<ArticleCriteria, Observable<Pair<String, String>>> {
    val isTemporaryClone = it.isATemporaryClone
    val isTheOriginalToken = it.tokenIsOriginalHere

    if (isTemporaryClone) {
        if (!isTheOriginalToken) {
            return@Func1 paramsError("Token is always original for temp articles")
        }

        return@Func1 mJobRunner.doNotRun(DeleteArticleJob.TAG)
                            .doOnNext(deletePersonalActionById(articleId))
    }

    runArticleJobAsync(DeleteArticleJob.TAG, it)
})
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Kotlin, the return@label syntax is used for specifying which function among several nested ones this statement returns from.

It works with function literals (lambdas) and local functions. Non-labeled return statements return from the nearest (i.e. innermost) enclosing fun (ignoring lambdas). Consider this function:

fun foo(ints: List<Int>) {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}

Here, return will finish the execution of foo, not just the lambda.

But if you want to return from any other function (a lambda or an outer fun) you have to specify it as a label at return statement:

fun foo(ints: List<Int>) {
    ints.forEach {
        if (it == 0) return@forEach // implicit label for lambda passed to forEach
        print(it)
    }
}

fun foo(ints: List<Int>): List<String> {
    val result = ints.map f@{
        if (it == 0) return@f "zero" // return at named label
        if (it == -1) return emptyList() // return at foo
        "number $it" // expression returned from lambda
    }
    return result
}

foo(listOf(1, -1, 1)) // []
foo(listOf(1, 0, 1)) // ["number 1", "zero", "number 1"]

Non-local return (i.e. return from outer functions) from a lambda is only supported for local and inline functions, because if a lambda is not inlined (or a function is placed inside an object), it is not guaranteed to be called only inside the enclosing function (e.g. it can be stored in a variable and called later), and the non-local return would make no sense in this case.


There is also a similar syntax for qualified this, which is used to reference receivers of outer scopes: this@outer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...