是什么引起以下运算符重载来交换操作数?

时间:2018-09-21 18:49:43

标签: scala operator-overloading scala-compiler

我正在使用Scala语言定义2个运算符:PressGas():++互为确切的镜像:++:,它们显然不是可交换的:{{1 }}。

这是我的Scala测试代码:

a :++ b == b ++: a

第一个测试看起来很好,但是运行时出现以下错误:

a :++ b != a ++: b

从打印的消息中可以看出,scala会覆盖我的运算符并自行反转操作数,是什么导致scala编译器以这种方式运行?是一个错误吗?

我正在使用最新的scala 2.11和最新的Java 8u181进行测试。

1 个答案:

答案 0 :(得分:3)

使用Scala的语言specification

  

操作员的关联性由操作员的最后一个决定   字符。以冒号“:”结尾的运算符是右关联的。所有   其他运算符是左关联的。

这是一个演示:

scala> case class Test(name: String) {
     |     def ++:(that: Test) = println(s"Called ++: on $this with argument $that")
     |     def :++(that: Test) = println(s"Called :++ on $this with argument $that")
     | }
defined class Test

scala> val (x, y) = (Test("x"), Test("y"))
x: Test = Test(x)
y: Test = Test(y)

scala> x ++: y
Called ++: on Test(y) with argument Test(x)

scala> x :++ y
Called :++ on Test(x) with argument Test(y)

因此,当您在代码中说p1 ++: p2时,执行的是p2.++:(p1),它等效于p1 :++ p2。这意味着您的两个运算符实际上严格相等。