Scala 重载复合运算符,如+=

Scala 重载复合运算符,如+=,scala,operator-overloading,compound-assignment,Scala,Operator Overloading,Compound Assignment,可以直接在Scala中重载运算符+=吗?它对于某些复杂类型可能很有用,其中a+=b的实现可能比a=a+b更高效、更简单 我最近遇到的一个案例是,我从jMonkeyEngine(com.jme.math)为Vector3f提供操作符。一个自然的实现可能看起来像: import com.jme3.math.{Matrix3f, Vector3f} object JMEMathOperators { implicit class Vector3fMath(val a: Vector3

可以直接在Scala中重载运算符+=吗?它对于某些复杂类型可能很有用,其中a+=b的实现可能比a=a+b更高效、更简单

我最近遇到的一个案例是,我从jMonkeyEngine(com.jme.math)为
Vector3f
提供操作符。一个自然的实现可能看起来像:

  import com.jme3.math.{Matrix3f, Vector3f}

  object JMEMathOperators {
    implicit class Vector3fMath(val a: Vector3f) extends AnyVal {
      def - (b: Vector3f) = a subtract b
      def + (b: Vector3f) = a add b
      def * (b: Vector3f) = a mult b
      def * (b: Float) = a mult b

      def += (b: Vector3f) = a addLocal b
    }
  }

尽管没有编译错误,但从未调用我的
+=
实现。在这种情况下,差异并不是那么重要,
addLocal
的效率只比
add
稍微好一点,但可以想象,在某些复杂的类中,差异可能很重要。

当然可以为
+=
提供自己的实现,但我怀疑你的问题来自隐性转换

如果
Vector3f
已经提供了
+=
方法,调用它将不会触发从
Vector3f
Vector3fMath
的隐式转换

例如,如果
a
b
都是
Vector3f
,则执行以下操作:

a += b
将调用
Vector3f
上的
+=
方法,这是完全预期的

为了触发隐式转换,您需要使用尚未定义的方法
Vector3f
。你必须选择另一个名字,也许是另一个符号


更新
好的,所以
Vector3f
没有定义
+=
(因为它是一个Java类)。那么您的代码应该可以正常工作,错误可能在其他地方。

Vector3f是Java对象,因此它当然不提供任何像+=。但是你是对的,隐式转换可能会使这里的情况有所不同。我错了,+=被调用。我认为这不是因为放在相应行上的断点没有触发,而是通过将println调用放在+和+=中,我可以看到它被调用了。哪个IDE?删除
扩展AnyVal
是否允许您设置断点?@som snytt我正在使用InteliJ IDEA 13.1 Ultimate和Scala插件。是的,删除“extendsanyval”后,断点将命中。