Scala DSL:使用无参数方法链接的方法

时间:2012-02-07 09:32:58

标签: scala dsl

我正在创建一个小scala DSL并遇到以下问题,我真的没有解决方案。我想要实现的一个小概念性例子:

(Compute
 write "hello"
 read 'name
 calc()
 calc()
 write "hello" + 'name
)

定义此dsl的代码大致如下:

Object Compute extends Compute{
  ...
 implicit def str2Message:Message = ...
}
class Compute{
 def write(msg:Message):Compute = ...
 def read(s:Symbol):Compute = ...
 def calc():Compute = { ... }
}

现在的问题是:如何在计算后摆脱这些括号?可能吗?如果是这样,怎么样?只是在定义中省略它们并没有帮助,因为编译错误。

3 个答案:

答案 0 :(得分:3)

不可能摆脱括号,但你可以替换它。例如:

object it

class Compute {
 def calc(x: it.type):Compute = { ... }

(Compute
 write "hello"
 read 'name
 calc it
 calc it
 write "hello" + 'name
)

要扩展一点,只要Scala看到这样的东西:

object method
non-reserved-word

它假设它意味着object.method(non-reserved-word)。相反,只要它看到这样的东西:

object method object
method2 object2

假设这些是两个独立的陈述,如object.method(object); method2.object,期望method2成为新对象,object2成为方法。

这些假设是Scala语法的一部分:它是故意这样做的。

答案 1 :(得分:3)

好吧,我想,我找到了一个可以接受的解决方案......我现在实现了这种可能的语法

 | write "hello"
 | read 'name
 | calc
 | calc
 | write "hello " + 'name 

使用名为“|”的对象,我几乎可以写出我想要的dsl。正常的,“;”如果无参数,则在calc之后需要。这里的技巧是接受DSL对象本身(这里,它是下一行的“|”)。使该参数隐式也允许calc作为此代码中的最后一个语句。 好吧,看起来绝对不可能按照我想要的方式拥有它,但这也没关系

答案 2 :(得分:-1)

首先尝试从calc的定义中删除括号。其次尝试在整体上使用花括号而不是括号。大括号和括号并不意味着相同,我发现括号在单行代码中效果最好(除非使用分号)。另请参阅What is the formal difference in Scala between braces and parentheses, and when should they be used?