13-非局部返回
11.3.3 非局部返回
在Kotlin中,使用无限定符的return语句可以退出一个有名称的函数或者匿名函数。如果要退出Lambda表达式,必须使用一个标签。无标签的return 在Lambda表达式内是禁止使用的,因为Lambda表达式不允许包含它的函数直接返回。
fun foo() {
ordinaryFunction {
return //错误,不允许foo函数返回
}
}
但是,如果Lambda表达式传入的是内联函数,那么return语句也是允许被内联的。
fun foo() {
inlineFunction {
return // 正确,Lambda表达式是内联的
}
}
在Kotlin中,将这种位于Lambda表达式中,但能够退出闭包函数的返回称为非局部返回。在Kotlin的循环语句中经常会遇到这种结构,下面是官方给出的非局部返回的例子。
fun hasZeros(ints: List<Int>): Boolean{
ints.forEach{
if(it == 0) return true
}
return false
}
有些时候,内联函数并不会在自己的函数体内直接调用传入的Lambda表达式参数,而是通过其他的执行上下文来完成调用,如本地局部对象或嵌套函数。对于这些情况,非局部的控制流不允许出现在Lambda表达式中,可以使用crossinline修饰符来标记Lambda表达式参数。
inline fun f(crossinline body: () -> Unit) {
val f = object: Runnable {
override fun run() = body()
}
// …
}