Kotlin中尾随lambda语法的目的是什么?

28
在 Kotlin 中,有一个惯例:如果一个函数的最后一个参数接受一个函数,那么作为对应参数传递的 lambda 表达式可以放在括号外面: Passing a lambda to the last parameter
val product = items.fold(1) { acc, e -> acc * e }
这个语法的目的是什么?

提示:您是否查看了fold函数的定义或理解它的作用? - OneCricketeer
4
@cricket_007,我认为这个问题与代码的工作方式无关,而是与语法的动机有关。vkelman,请参考 https://kotlinlang.org/docs/reference/type-safe-builders.html 查看一些使用lambda在括号外部创建DSL(领域特定语言)的Kotlin代码示例(在我看来非常好)。 - SpencerPark
@SpencerPark,是的,这些块也适用于DSL,但我不确定问题是关于什么的。关于fold(),第二个参数是一个函数(acc: R, nextElement: T) -> R- https://kotlinlang.org/docs/reference/lambdas.html - OneCricketeer
4
这个例子是直接从参考文档中引用的,但问题是“这个语法的目的是什么?”。看起来像是一个关于语言设计的问题,但我们需要让vkelman澄清一下。 - SpencerPark
嗯,“目的”是为了匹配方法 API。但这不是唯一的编写方式。就像最后那个链接中展示的那样,它也可以写成 items.fold(1, {...}) - OneCricketeer
7
好的,我会尽力进行翻译。以下是需要翻译的内容:Well, I explicitly asked what is the purpose of this (confusing to me) syntax. I didn't ask what fold is doing. The answer I got - it allows for DSL. In my opinion, often those syntactic sugar things intended to prettify a language actually make code harder to understand.我的问题很明确,我想知道这个(对我来说很困惑的)语法的目的是什么,而不是fold在做什么。我得到的回答是-它允许DSL。 我认为,通常那些旨在美化语言的语法糖实际上会使代码更难理解。 - vkelman
1个回答

27

这种语法使得 Kotlin 拥有出色的领域特定语言 (DSL) 能力,它使函数看起来像语言结构。例如:

with(car) {
   startUp()
   goToDestination()
}

这里with看起来像是语言结构,但实际上它只是一个简单的函数,最后一个参数是lambda表达式。

这导致了一些优雅的事情,比如Kotlin HTML DSL


1
一个特定领域语言在 Kotlin 中有什么用处?如果你正在为一个特定领域编写代码,为什么不直接使用该领域的特定语言呢? - SMBiggs
@SMBiggs 大多数 DSL 都是使用传统语言实现的,因为仅为了 DSL 创建整个语言通常不值得。有些语言比其他语言更适合于 DSL,例如 Groovy(标准 Gradle DSL 是用 Groovy 实现的,尽管最近也可以使用 Kotlin,并且流行的 CI DSL,如 Jenkins Job DSL 也是用 Groovy 实现的)。还有一些在 Java 中的 DSL,例如 Mockito 用于测试,尽管作为一种语言,Java 可能不太适合 DSL。 - Adam Burley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接