【问题标题】:Implicit return from lambda in KotlinKotlin 中 lambda 的隐式返回
【发布时间】:2017-01-12 19:01:00
【问题描述】:

即使您省略了return 语句,lambda 的最后一行似乎总是返回该值。它是否正确?它是否记录在任何地方?

fun main(args: Array<String>) {
    val nums = arrayOf(1, 2, 3)
    val numsPlusOne = nums.map { it -> 
        val r = it + 1
        r
    }
    // numsPlusOne = [2, 3, 4]
}

【问题讨论】:

  • 只是一个有用的提示,您可以将其缩短为val numsPlusOne = nums.map { it + 1 }(因为如果未指定,则隐含it,如果it + 1是最后一行,则其结果将作为@hotkey返回解释)

标签: kotlin


【解决方案1】:

是的,这是正确的,如果 lambda 的最后一条语句是表达式,则将其视为返回值。

这是what the reference says(感谢@KirillRakhman):

我们可以使用qualified return 语法从 lambda 显式返回一个值。否则,最后一个表达式的值被隐式返回。因此,以下两个sn-ps是等价的:

ints.filter {
    val shouldFilter = it > 0 
    shouldFilter
}

ints.filter {
    val shouldFilter = it > 0 
    return@filter shouldFilter
}

if (that's why there's no ternary operator)whentry-catch 块的最后一条语句语义也是如此,这些语句本身就是表达式:

val foo = if (bar) { 
    doSomething()
    baz 
} else { 
    doSomethingElse()
    qux 
}

另见:examples for when and try-catch

因此,lambda 在这方面与语言结构是一致的。


如果您想在 lambda 中创建明确的 return 语句,请使用 return@label syntax(也称为 another answer with examples)。相反,未标记的 return 与最近的 fun 一起工作(忽略 lambda),因此只能出现在那些为 inlined 的 lambda 中。

有一个language proposal 可以为发射代码块中的值添加特殊语法,但它被拒绝了。

【讨论】:

  • “如果 lambda 的最后一个语句是一个表达式”——我找不到明确的定义来源,但我认为将“表达式”称为“语句”是不正确的。 Kotlin 文档只说“隐式返回最后一个表达式的值”。我的理解是语句通常不会产生值,expression 不是statement 的类型
  • @mowwwalker 好吧,虽然这是有争议的,但在the Kotlin grammar 中,一种语句是表达式,它可能是悬空的未使用值或返回值被忽略的函数调用。跨度>
  • 啊,太棒了,那就解决了:)
猜你喜欢
  • 1970-01-01
  • 2021-12-22
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多