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

时间:2017-01-27 06:46:44

标签: scala operator-overloading operator-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如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

回答关于modyfing运算符优先级的问题 - 要改变它你基本上只需要更改自定义运算符的第一个字符 - 这就是scala在中缀运算符之前找出的方法,只需查看第一个角色。所以,如果你,例如。添加和运算符*|+

  1. *|*具有相同的优先级,与**一样。
  2. “更大”的优先级高于+|+,就像*+一样。
  3. 不幸的是,目前没有其他方法可以解决这个问题。没有自定义注释/权重等,以避免使阅读代码过于模糊。

    优先规则在这里得到了很好的总结 - Operator precedence in Scala

    关于您的问题 - 您会得到正确的结果。

    *|*以及*是左关联运算符,其第一个字符*,因此它们具有相同的先行。

    您的操作:

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

    转换为

    a * b + c + d * a,即1 * 3 + 9 + 12 * 1

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