我正在研究DSL,并且在链中使用方法作为中缀运算符时遇到了问题。我会试着用一些代码来解释它。我有一个特质 Term 及个案类别 LiteralVariable 延伸它。我想使用一些运算符构造一个术语实例列表。

case class Expr(val terms: List[Term]) {
 def +(v: String) = Expr(Literal(v) :: terms)
 def -->(func: List[String] => List[String]) = terms match {
  case Literal(v) :: ts => Expr(Variable(v, func) :: ts)
  case _ => throw new Exception("Can only apply function on literal")
 }
}

object foo {
 def bar(name: String) = Expr(Literal(name) :: Nil)
}

// some functions
val one = ... 
val all = ...

// works
foo bar "x"        
// res1: Expr = Expr(List(Literal(x)))

// works not
foo bar "x" --> all
// error: value --> is not a member of java.lang.String

// works
(foo bar "x") --> all 
// res1: Expr = Expr(List(Variable(x,<function1>)))

我会期望这将等同于 foo.bar("x").-->(all) 但解释器似乎把它看作是 foo.bar("x".-->(all)).

有帮助吗?

解决方案

你可以找到 运算符优先级 这里:

Scala中的运算符优先级

根据第一个答案 - 与字母相比,具有更高的优先级。所以编译器像这样分组表达式:

foo bar ("x" --> all)

如果您将替换 --> 具有较低优先级的东西(例如字母),那么它应该编译。例如:

foo bar "x" to all

您也可以选择更高优先级的运算符,而不是 bar.类似的东西 ~~> 会做,因为 ~ 是特殊的字符,它具有最高的优先级:

foo ~~> "x" --> all
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top