返回和跳转

2026-07-15 17:25:24 来源: 爱吃喝 点击数: 

Kotlin 有三种结构性跳转表达式:

  • return 默认情况下,会从最近的封闭函数或匿名函数返回。

  • break 终止最近的循环。

  • continue 继续到最近的外层循环的下一步。

所有这些表达都可以作为更大表达的一部分使用:

val s = person.name ?: return

这些表达式的类型是 Nothing 类型。爱吃喝

Break and continue labels

在 Kotlin 中,任何表达式都可以标记上一个标签。标签的形式是一个标识符后跟 @ 符号,比如 abc@ 或 fooBar@。
要给表达式标记标签,只需在它前面加上一个标签即可。

loop@ for (i in 1..100) {
    // ...
}

现在,你可以用标签来限定 break 或 continue:

loop@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) break@loop
    }
}

带标签的 break 会跳到标有该标签的循环之后的执行点。continue 则会进入该循环的下一次迭代。

 

在某些情况下,你可以在不显式定义标签的情况下非局部地使用 break 和 continue。这种非局部用法在用于封闭内联函数的 lambda 表达式中是有效的。

Return to labels

在 Kotlin 中,可以使用函数字面量、本地函数和对象表达式来嵌套函数。限定的 return 允许你从外层函数返回。爱河池

最重要的用例是从 lambda 表达式返回。要从 lambda 表达式返回,需要给它加上标签并限定返回:

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with explicit label")
}
1245 done with explicit label

现在,它只从 lambda 表达式中返回。通常使用隐式标签更方便,因为这样的标签与传递 lambda 的函数同名。

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with implicit label")
}
1245 done with implicit label

或者,你可以用匿名函数替换 lambda 表达式。匿名函数里的 return 语句会从匿名函数本身返回。

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return  // local return to the caller of the anonymous function - the forEach loop
        print(value)
    })
    print(" done with anonymous function")
}
1245 done with anonymous function

注意,前面三个例子中局部返回的使用类似于普通循环中使用 continue。

没有与 break 完全对应的东西,但可以通过添加一个外部的 run lambda 并从中非局部返回来模拟它:

fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}
12 done with nested loop

这里的非本地返回是可能的,因为嵌套的 forEach() lambda 表现得像一个内联函数。

在返回值时,解析器优先考虑限定返回:

return@a 1

This means "return 1 at label @a " rather than "return a labeled expression (@a 1) ".
这意味着 "return 1 at label @a ",而不是"return a labeled expression (@a 1) "。

 

在某些情况下,你可以在不使用标签的情况下从 lambda 表达式返回。这种非局部返回位于 lambda 中,但会退出包含它的内联函数。


上一篇:多美元字符串插值
下一篇:返回列表
关键字:

河池新闻

图说城市 图说天下

阅读排行 阅读排行


爱河池