如何修改自定义scala运算符的优先级

how to modify self-defined scala operators' precedence

是否可以修改自定义运算符的优先级? 例如,我用完全自定义的运算符实现初等算术。

  case class Memory(name:String){
    var num:Num = null

    def <<=(x:Num): Unit = {
      println(s"assign ${x.value}")
      this.num = x
    }
  }

  case class Num(var value:Int) {
    def +|+(x:Num) = {
      println("%d + %d = %d".format( value,x.value,x.value + value ))
      Num(value + x.value)
    }
    def *|*(x:Num) = {
      println("%d * %d = %d".format( value,x.value,x.value * value ))

      Num(value * x.value)
    }
  }


  val m1 = Memory("R")

  val a = Num(1)
  val b = Num(3)
  val c = Num(9)
  val d = Num(12)

  m1 <<= a *|* b +|+ c +|+ d *|* a

  println("final m1 ",m1.num.value)

结果是

1 * 3 = 3
3 + 9 = 12
12 * 1 = 12
12 + 12 = 24
assign 24
(final m1 ,24)

显然优先级是正确的。我希望 *|** 具有相同的优先级并且 +|++ 相同,<<= 也与 = 相同。 Scala 是如何解决的?

回答有关 modyfing 运算符优先级的问题 - 要更改它,您基本上只需更改自定义运算符的 第一个字符 - 这就是 scala 计算中缀运算符优先级的方式, 只看第一个字符。所以如果你例如。添加运算符 *|+:

  1. 它将与 *|* 具有相同的优先级,与 ** 相同。
  2. +|+“更大”的优先级,就像 *+.

不幸的是,目前没有其他方法可以处理它。没有自定义 annotations/weights 等等以避免阅读代码太模糊。

此处很好地总结了优先规则 - Operator precedence in Scala

关于你的问题 - 你得到了正确的结果。

*|**都是left-associative运算符,它们的第一个字符*,所以它们有同等优先权。

您的操作:

a *|* b +|+ c +|+ d *|* a

转换为

a * b + c + d * a,也就是1 * 3 + 9 + 12 * 1.

应用标准优先规则 - (a*b) + c + (d*a) 结果为 24。