【问题标题】:how to modify self-defined scala operators' precedence如何修改自定义scala运算符的优先级
【发布时间】:2017-01-27 06:46:43
【问题描述】:

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

  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)

显然优先级是正确的。我希望*|**+|++ 具有相同的优先级,&lt;&lt;= 也与= 等效。 scala 是如何计算出来的?

【问题讨论】:

  • @jwvh 你是对的。订单正是我想要的。但我不知道 scala 如何计算出正确的优先级?

标签: scala operator-overloading operator-precedence


【解决方案1】:

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

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

不幸的是,目前没有其他方法可以处理它。没有自定义注解/权重等,避免让阅读代码过于模糊。

这里很好地总结了优先规则 - 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。

【讨论】:

  • 为了完整起见,值得一提的是上述规则的例外情况,即带有: 的操作结束 是右关联的。例如,列表 cons 运算符 (::) 如何知道类型是 List - 它从最后一个元素 Nil 派生它。
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 2012-04-15
  • 2020-03-26
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
相关资源
最近更新 更多