Составные операторы перегрузки, такие как +=

Возможно ли перегрузить оператор += непосредственно в Scala? Это может быть полезно для некоторых сложных типов, где a += b может иметь более эффективную и простую реализацию, чем a = a + b.

Случай, с которым я столкнулся недавно, - это предоставление операторов для Vector3f от jMonkeyEngine (com.jme.math). Естественная реализация может выглядеть так:

  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, но можно представить, что есть некоторые сложные классы, где разница может быть важной.

1 ответ

Решение

Конечно, можно предоставить собственную реализацию для +=, но я подозреваю, что ваша проблема происходит от неявного преобразования.

Если Vector3f уже обеспечивает += метод, вызывающий его, не вызовет неявное преобразование из Vector3f в Vector3fMath,

Например, если a а также b оба Vector3f, делая

a += b

позвоню += метод на Vector3f, что вполне ожидаемо.

Для запуска неявного преобразования необходимо использовать метод, который еще не определен Vector3f, Вы должны выбрать другое имя, возможно, другой символ.


Обновить

Итак Vector3f не определяет += (так как это класс Java). Тогда ваш код должен работать нормально, ошибка, вероятно, где-то еще.

Другие вопросы по тегам