尝试从lambda返回到封闭函数(foo
)时显示错误return is not allowed here
。
这是怎么回事?我在做错什么吗?
fun bar( baz: () -> Unit ) {
// Empty function
}
fun foo() : Unit? {
return null // this works fine
bar {
return null // shows error 'return is not allowed here'
}
}
编辑:
我也尝试过:
...
bar {
return@bar null
}
...
但这会导致错误Null can not be a value of a non-null type Unit
答案 0 :(得分:2)
答案 1 :(得分:1)
在Kotlin中有一条规则-return
总是从fun
返回。可以使用return@<label/function name>
从函数或lambda返回。
接下来,出现inline fun
。内联函数不是真正的函数,它们内联到调用站点中,因此,可以从作为该函数参数的lambda内部进行返回(标准库中有很多示例)
总结:
inline fun bar(a: () -> Unit) { a() }
fun buz() : Int {
bar { return 42 } /// such return is only possible to inline fun
return 10
}
val x = buz() /// will be 42
bar { if (something) return@bar }
这里我们从lambda返回,而不是从函数返回。
答案 2 :(得分:1)
我们都知道 kotlin 规范中的事实。但背后的原因一点也不微不足道。
问题是:为什么在 kotlin 中,默认情况下不允许在 lambda 中返回?
虽然这是一个老问题,但解释可能的原因对我来说仍然很重要。
乍一看,匿名函数和 lambda 的行为几乎相同:无名函数。但是,对于关键字 fun
,函数体中允许使用 return
,但没有 fun
(在 lambda 中)则不允许!不都是“功能”吗?
Lambda 确实是一个函数,但从字面上看,它更像是一个柏拉图式的“表达式”,它最终会以自己的设计意图来表示一个对象,因此实际上并不需要返回。
此外,由于“函数内联”和“非本地返回”功能/语法糖,lambda 中的 return
可能不明确。如果 lambda 是内联的,则返回的词法上下文是“非本地的”,这意味着它终止并从调用者函数返回。但是当它没有内联并且我们允许返回时,我们期望什么行为?这是矛盾和不直观的。
这就是为什么必须提供标签才能在没有内联的情况下在 lambda 中使用 return。当然,我们可以在任何地方使用标签返回,但它只会增加样板工作。