Scala DSL:如何添加 "nothing" 的单词?
Scala DSL: How to add words that do "nothing"?
我尝试在 Int
上构建一个简单的隐式 class 来为 Ints 添加一个函数:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
}
}
为了写得更自然,我希望 DSL 允许这样做(import Helper._
):
2 add "3" and add "4"
但我不知道如何执行 and
功能。我认为这个会起作用:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
def and: Int = i
}
}
但是如果没有括号它就不能工作(事实上,"2.add("3").and.add("4")
可以工作但是我觉得 DSL 的句号和括号太多了)。
谢谢
问题在于 and
现在用作后缀表示法,通常不建议这样做,因为它恰好创建了 problem with delimiting the expression。所以你可以写
(2 add "3" and) add "4"
但是
2 add "3" and add "4"
大致解析为
2.add("3").and(add)."4"
我会反对这样的 DSL。尤其是当刚接触 Scala 时,人们对 Scala 允许此类 DSL 的表现力很感兴趣,但你必须认真质疑它们的价值所在。
如果你真的想走这条路,你可以通过将虚拟 and
方法从后缀变为中缀,添加另一个虚拟参数,例如then
:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
}
implicit class AndThen[A](in: A) {
def and(t: then.type): A = in
}
object then
}
import Helper._
2 add "3" and then add "4"
问题正如0__所述。除了 0__ 的解决方案之外,我还没有看到如何在没有括号的情况下完全实现这一目标的方法。
作为替代方案,这里有一个版本只需要在链式 add
调用周围加上括号,比原来的解决方案要少,而且不需要额外的关键字:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
def and(add: AddWord): Int = i + add.str.toInt
}
val add = AddWord
case class AddWord(private[Helper] val str: String)
}
可用作:
import Helper._
1 add "3" and add("4") and add("5")
我尝试在 Int
上构建一个简单的隐式 class 来为 Ints 添加一个函数:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
}
}
为了写得更自然,我希望 DSL 允许这样做(import Helper._
):
2 add "3" and add "4"
但我不知道如何执行 and
功能。我认为这个会起作用:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
def and: Int = i
}
}
但是如果没有括号它就不能工作(事实上,"2.add("3").and.add("4")
可以工作但是我觉得 DSL 的句号和括号太多了)。
谢谢
问题在于 and
现在用作后缀表示法,通常不建议这样做,因为它恰好创建了 problem with delimiting the expression。所以你可以写
(2 add "3" and) add "4"
但是
2 add "3" and add "4"
大致解析为
2.add("3").and(add)."4"
我会反对这样的 DSL。尤其是当刚接触 Scala 时,人们对 Scala 允许此类 DSL 的表现力很感兴趣,但你必须认真质疑它们的价值所在。
如果你真的想走这条路,你可以通过将虚拟 and
方法从后缀变为中缀,添加另一个虚拟参数,例如then
:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
}
implicit class AndThen[A](in: A) {
def and(t: then.type): A = in
}
object then
}
import Helper._
2 add "3" and then add "4"
问题正如0__所述。除了 0__ 的解决方案之外,我还没有看到如何在没有括号的情况下完全实现这一目标的方法。
作为替代方案,这里有一个版本只需要在链式 add
调用周围加上括号,比原来的解决方案要少,而且不需要额外的关键字:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
def and(add: AddWord): Int = i + add.str.toInt
}
val add = AddWord
case class AddWord(private[Helper] val str: String)
}
可用作:
import Helper._
1 add "3" and add("4") and add("5")