Scala 中的 DSL 是什么?

What is DSL in Scala?

浏览各种与 Scala 相关的内容 material,术语 DSL 在很多地方都被使用。

Google 搜索表明它是域特定语言。

它到底是什么意思,为什么在学习 Java 等其他语言时没有遇到这个术语?

正如其他人所指出的,问题的第一部分 ("what is a DSL?") 基本上由 What is a DSL and where should I use it?

回答

我将尝试回答第二部分:为什么 DSL 在 Scala 中如此受欢迎?

原因是 Scala(与 Java 等其他语言相反)提供了许多句法工具来提供 DSL。

例如Scala有中缀方法的应用:

someObject.someMethod(someArgument)

// can be written as

someObject someMethod someArgument

这使得在语言中引入自定义 "operators" 变得非常容易。一个值得注意的例子是 akka DSL,用于向 actor 发送消息:

actor ! message

这是一个模仿 Erlang 语法的 DSL。

Scala 中语法工具的另一个例子是 "trailing block argument"(不确定它有一个准确的名称):

def someMethod(x: Int)(y: String) = ???

// can be invoked as
someMethod(42)("foo")

// but also as
someMethod(42) { "foo" }

当最后一个参数是一个函数时,这很有趣:

def someOtherMethod[A, B](x: A)(f: A => B): B = ???

someOtherMethod(42) { a =>
  // ...a very long body
}

在其他语言中,块({ ... })通常保留给built-in control-flow结构(例如ifwhilefor, 等),但在 Scala 中,您可以使用此语法工具来构建类似于 built-in 控制结构的自定义方法。

仅这两个特性就足以解释为什么 DSL 在 Scala 社区中如此普遍。

更深入一点,我们还可以提到隐式转换,它允许向任何现有类型添加自定义方法。例如

implicit class TimesOps(x: Int) {
  def times(y: Int): Int = x * y
}

// then use as

2 times 4 // 8

这个例子结合了中缀方法应用和隐式转换的使用。