Псевдоним Java-метода в Scala

Учитывая интерфейс Java

interface Value {

  Value add(Value argument);

}

(поскольку Java не поддерживает символы вроде + в качестве имен методов), возможно ли определить метод псевдонима + для псевдонима add, чтобы при использовании класса из Scala можно было написать

  result = value1 + value2

вместо

  result = value1.add(value2)

or

  result = value1 add value2

Псевдоним должен автоматически применяться ко всем классам, реализующим интерфейс.


person Christian Fries    schedule 25.05.2020    source источник
comment
Я собирался предложить scala.annotation.alpha в Dotty, но это явно не работает - он не отменяет фактический метод добавления, но когда создаются метод добавления и оператор с тем же псевдонимом, он говорит, что существует двойное определение scastie.scala-lang.org/UvqrkDFjSXmp9yOYIRSNCg, что странно   -  person user    schedule 25.05.2020
comment
См. Этот очень похожий вопрос: stackoverflow.com/ questions / 33279472 /   -  person user    schedule 25.05.2020
comment
@user вы не можете аннотировать интерфейс Java с помощью аннотации макроса Scala.   -  person Dmytro Mitin    schedule 25.05.2020
comment
@DmytroMitin Нет, но вы можете аннотировать классы Scala, реализующие эти интерфейсы, и, возможно, генерировать эти методы   -  person user    schedule 25.05.2020


Ответы (1)


Вы можете добавить расширение внешнего метода через неявный класс

object ValueImplicits {

  implicit class ValueOps(val value: Value) extends AnyVal {
    def +(v: Value): Value = value.add(v)
  }

}

Теперь это может работать так

import ValueImplicits._

val v1 = new Value {}
val v2 = new Value {}
val v3 = v1 + v2

Вы можете избежать импорта, если можете создать сопутствующий объект для интерфейса Value в том же пакете.

object Value {

  implicit class ValueOps(val value: Value) extends AnyVal {
    def +(v: Value): Value = value.add(v)
  }

}

Неявное разрешение проверяет сопутствующие объекты без явного импорта.

person Ivan Stanislavciuc    schedule 25.05.2020
comment
Companion - это не просто объект с тем же именем, что и класс / черта, и в том же пакете. Он должен быть в той же области и в том же файле. В противном случае это просто объект с таким же именем, но не компаньон. Таким образом, никто не может создать объект-компаньон для интерфейса Java. - person Dmytro Mitin; 25.05.2020