返回和跳转
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 中,但会退出包含它的内联函数。





