Kotlin:“ return @”是什么意思?


71

我在我的一个项目中使用RxJava,我使用Android Studio插件将我的一个类转换为Kotlin,并且在map flatMaplambda(java中的Func1)之一中,中间体返回如下所示@Func1

我不知道这是什么意思。

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)
})

Answers:


104

在Kotlin中,return@label语法用于指定该语句从几个嵌套函数中返回哪个函数。

它与函数文字(lambda)和局部函数一起使用。未标记的return语句从最近的(即最里面的)封闭fun(忽略lambda)返回。考虑以下功能:

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

在这里,return将完成执行foo,而不仅仅是lambda。

但是,如果要从其他任何函数(lambda或external fun)返回,则必须在return语句中将其指定为标签:

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"]

Lambda的非本地返回(即从外部函数返回)仅支持本地内联函数,因为如果未内联Lambda(或将函数放置在对象内),则不能保证仅在内部调用封闭函数(例如,可以将其存储在变量中,然后再调用),在这种情况下,非本地返回将毫无意义。


合格this语法也有类似的语法,用于引用外部范围的接收者:this@outer


1
谢谢!如果Kotlin官方文档像您在此处所做的示例那样更详细地介绍了这一点,那将是很好的。
Michael Peterson

10

return@name确定return应对其应用关闭语句的位置。

在Kotlin中,您可以从嵌套闭包调用return来完成外部闭包。在Java中是不可能的。

通常,您可以省略@name

在您的示例中,您不能忽略它,因为它Func1是在另一个函数中使用的。


1
如果代码是在函数体内编写的,@Func1则不能省略。
热键

您能否详细说明在哪些条件下@Func1可以省略?我试图something.flatMap(...)在顶级声明中使用该表达式,但出现“return此处不允许”错误。
热键

谢谢!@hotkey和mklimek的答案都是正确的,hotkey的答案稍微复杂一点,我都投票支持并检查hotkey的:)
Glenn Sonna

是否可以将其用于when(与Kotlin等效的开关盒)?很多时候我想在缩进太多时打破它……
android开发人员
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.