使用 Kotlin lambda 表达式时删除括号有什么好处?

问题描述 投票:0回答:3

考虑这里给出的示例:https://stackoverflow.com/a/53376287/11819720

fun onClick(action: () -> Unit) { ... } 

view.onClick({ toast(it.toString())} )
view.onClick() {toast(it.toString()) }
view.onClick { toast(it.toString()) }

和这段代码:

fun convert(x: Double, converter: (Double) -> Double): Double{
    val result = converter(x)
    println("$x is converted to $result")
    return result
}
fun convertFive (converter: (Int) -> double): Double{
    val result = converter(5)
    println(" 5 is converted to $result")
    return result
}
fun main (args: Array<String>){
    convert(20.0) { it * 1.8 + 32 }
    convertFive { it * 1.8 + 32 }
}

看来我们的努力是为了避免写几个括号,冒着让读者感到困惑的风险。 如果保持标准不是更好吗?使用第二个示例中的函数的通常方法是:

convert(20, {it * 1.8 + 32})
convertFive({it * 1.8 = 32})

但是 IntelliJ 会抱怨并建议将 lambda 从括号中移出。为什么?有实际好处吗?看起来像是写

10 + 2 * 5 / 34
而不是
10 + (2 * 5) / 34

function kotlin lambda syntax
3个回答
3
投票

尾随大括号 lambda 的真正好处在于,像所有最好的语言功能一样,它改变了您的思维方式。

您提供的示例用括号编写得很好,我同意 IntelliJ 建议始终使用尾随形式是不必要的......

但是当我写下这样的东西时:

with(someObject) {
    doSomething();
    doSomethingElse();
}

看起来就像我正在使用该语言的一个很酷的新功能,即使我实际上只是调用一个函数。

结果是,人们开始思考他们可以编写向语言添加东西的函数,因为他们有点可以,这导致他们为使用他们的代码的人创建新的做事方式。

类型安全构建器模式就是一个很好的例子。许多 Kotlin 语言功能协同工作,因此,即使它只是调用函数和传递 lambda,它也为使用它的开发人员提供了新的体验。

他们获得了一种全新的方式来实例化复杂对象,这种方式比旧方式更加自然,并且不需要为此在语言中添加任何内容——所有的小构建块功能都可以用于许多其他事情。


1
投票

根本没有任何实际好处,只是一个约定。

关于你所说的“保持标准”。你到底从哪里得到“通常的方式”?据我所知,没有全局编程约定,只有特定于语言的约定,因此这种表示法根据定义是标准的。

约定很重要,因为它们可以让熟悉语法的人更轻松地阅读代码。这些约定也反映了语言的用法。通过 Kotlin,他们提倡一种非常实用的风格,大量使用 lambda 和内联函数,因此“括号外的 lambda”对于保持代码干净和明确是必要的。

正如@Tenfour04 在评论中所说,您的示例确实没有反映语法的预期用法。一般来说,你有多条线,即使没有,图案也应该传达更多的东西。以

measureTimeMillis
函数为例:

measureTimeMillis {

    askQuestion()
    comment()
    answerQuestion()
}

通过将 lambda 放在括号之外,即使对于非技术读者来说,也可以立即清楚该函数的作用,这正是约定的用途。


1
投票

更接近你的例子。假设您需要转换一个数字数组并对所有正数进行平方。比较一下更容易阅读的内容:

val result = arrayOf(1.0, 2.0, -3.0).map({ number ->
        convert(number, {
            if (it > 0) it * it else it
        })
    })
val result = arrayOf(1.0, 2.0, -3.0).map { number ->
        convert(number) {
            if (it > 0) it * it else it
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.