Non-local returns
在Kotlin中,我们可以使用正常的、不受限制的return语句来退出一个函数或匿名函数。这意味着如果要退出lambda表达式,我们需要使用标签。在lambda表达式内部,空的return语句是禁止被使用的,因为lambda表达式不能使封闭函数返回:
fun foo() {
ordinaryFunction {
return // ERROR: can not make `foo` return here
}
}
但是如果一个被传递的函数lambda表达式是内联的,return也可以被内联,那么return将被允许:
fun foo() {
inlineFunction {
return // OK: the lambda is inlined
}
}
这样的return语句(位于lambda表达式中,但是可以退出封闭函数)被称为non-local returns。我们习惯于将这种设计用于循环中。
fun hasZeros(ints: List<Int>): Boolean {
ints.forEach {
if (it == 0) return true // returns from hasZeros
}
return false
}
需要注意的是一些inline函数可以调用传递给它们的lambda表达式,不是直接在函数体内部直接调用,而是从另外的执行上下文执行,比如局部对象或者嵌套函数。在这样的情况下,non-local控制流不允许在lambda表达式中。为了说明这一点,lambda参数需要被标记为crossinline修饰符:
inline fun f(crossinline body: () -> Unit) {
val f = object: Runnable {
override fun run() = body()
}
// ...
}
break和continue在内联lambda表达式中暂时不可用,但是计划支持这种特性。