什么是Scala中的DSL?

Man*_*oid 6 dsl scala

通过各种Scala相关材料,术语DSL在许多地方使用.

谷歌搜索告诉它是特定于域的语言.

究竟是什么意思,为什么在学习像Java这样的其他语言时,这个术语并没有出现?

Gab*_*lla 13

正如其他人所指出的那样,问题的第一部分("什么是DSL?")基本上由什么是DSL以及我应该在哪里使用它来回答?

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

原因是Scala(与Java等其他语言相对)提供了许多提供DSL的语法功能.

例如,Scala有中缀方法应用程序:

someObject.someMethod(someArgument)

// can be written as

someObject someMethod someArgument
Run Code Online (Sandbox Code Playgroud)

这使得在语言中引入自定义"操作符"非常容易.一个值得注意的例子是用于向演员发送消息的akka DSL:

actor ! message
Run Code Online (Sandbox Code Playgroud)

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

Scala中的语法功能的另一个例子是"尾随块参数"(不确定它是否具有精确的名称):

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

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

// but also as
someMethod(42) { "foo" }
Run Code Online (Sandbox Code Playgroud)

当最后一个参数是函数时,这是非常有趣的:

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

someOtherMethod(42) { a =>
  // ...a very long body
}
Run Code Online (Sandbox Code Playgroud)

在其他语言中,块({ ... })通常保留给内置的控制流结构(如if,while,for,等),但在Scala中您可以使用此语法设施建设类似于内置的控制结构自定义方法.

仅这两个特征就足以说明为什么DSL在Scala社区中如此普遍.

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

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

// then use as

2 times 4 // 8
Run Code Online (Sandbox Code Playgroud)

此示例结合使用中缀方法应用程序和隐式转换.