Search code examples
scalaoperator-overloadingcompound-assignment

Overload compound operators like +=


Is it possible to overload operator += directly in Scala? It might be useful for some complex types, where a += b may have more efficient and simpler implementation that a = a + b.

The case I encountered recently is I am providing operators for Vector3f from jMonkeyEngine (com.jme.math). A natural implementation could look like:

  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
    }
  }

In spite of no compile errors, my += implementation is never called. The difference is not that important in this case, addLocal efficiency is only marginally better than add, but one can image there are some complex classes where the difference could be important.


Solution

  • It's certainly possible to provide your own implementation for +=, but I suspect your issue comes from the implicit conversion.

    If Vector3f already provides a += method, calling it won't trigger the implicit conversion from Vector3f to Vector3fMath.

    For example, if a and b are both Vector3f, doing

    a += b
    

    will call the += method on Vector3f, which is completely expected.

    In order to trigger the implicit conversion you need to use a method which is not already defined Vector3f. You have to choose another name, perhaps another symbol.


    Update

    Ok, so Vector3f doesn't define a += (since it's a Java class). Then your code should work fine, the error is probably somewhere else.