Операторы - это методы
Одним из наиболее очевидных различий между Java и Scala является то, что Scala поддерживает перегрузку операторов.Фактически, Scala поддерживает вариант перегрузки операторов, который намного сильнее, чем все, что предлагается C ++, C # или даже Ruby.За очень немногими исключениями, любой символ может использоваться для определения пользовательского оператора.Это обеспечивает огромную гибкость в DSL и даже в среднем ежедневном API (например, List
и Map
).
Очевидно, что эта особая языковая функция не будет переводиться на Java так хорошо.Java не поддерживает перегрузки операторов любого вида, тем более сверхмощной формы, определенной в Scala.Таким образом, операторы Scala должны быть скомпилированы в совершенно несимвольную форму на уровне байт-кода, в противном случае взаимодействие Java будет непоправимо нарушено, и сама JVM не сможет проглотить результат.
Хорошее начальное место длявыбор этого перевода - способ объявления операторов в Scala: как методы.Каждый оператор Scala (включая унарные операторы, такие как !
) определяется как метод внутри класса:
abstract class List[+A] {
def ::[B >: A](e: B) = ...
def +[B >: A](e: B) = ...
}
Поскольку классы Scala становятся классами Java, а методы Scala становятся методами Java, наиболее очевидным переводом будетвозьмите каждый операторный метод и создайте соответствующий Java-метод с сильно переведенным именем.На самом деле, это именно то, что делает Scala.Приведенный выше класс скомпилируется в эквивалент этого кода Java:
public abstract class List<A> {
public <B super A> List<B> $colon$colon(B e) { ... }
public <B super A> List<B> $plus(B e) { ... }
}
Каждый допустимый символ в синтаксисе метода Scala имеет соответствующий перевод вида «$trans
«.Список поддерживаемых переводов - это одна из тех частей документации, которую вы ожидаете найти на веб-сайте Scala.Однако, увы, его нет.Ниже приведена таблица всех переводов, о которых мне известно:
┌────────────────┬─────────────┐
│ Scala Operator │ Compiles To │
├────────────────┼─────────────┤
│ = │ $eq │
├────────────────┼─────────────┤
│ > │ $greater │
├────────────────┼─────────────┤
│ < │ $less │
├────────────────┼─────────────┤
│ + │ $plus │
├────────────────┼─────────────┤
│ - │ $minus │
├────────────────┼─────────────┤
│ * │ $times │
├────────────────┼─────────────┤
│ / │ div │
├────────────────┼─────────────┤
│ ! │ $bang │
├────────────────┼─────────────┤
│ @ │ $at │
├────────────────┼─────────────┤
│ # │ $hash │
├────────────────┼─────────────┤
│ % │ $percent │
├────────────────┼─────────────┤
│ ^ │ $up │
├────────────────┼─────────────┤
│ & │ $amp │
├────────────────┼─────────────┤
│ ~ │ $tilde │
├────────────────┼─────────────┤
│ ? │ $qmark │
├────────────────┼─────────────┤
│ | │ $bar │
├────────────────┼─────────────┤
│ \ │ $bslash │
├────────────────┼─────────────┤
│ : │ $colon │
└────────────────┴─────────────┘
Используя эту таблицу, вы сможете получить «настоящее имя» любого оператора Scala, позволяя использовать его изнутри.Джава.Конечно, идея будет заключаться в том, что Java действительно поддерживает перегрузку операторов и может напрямую использовать операторы Scala, но почему-то я сомневаюсь, что это произойдет в ближайшее время.
**** Этот ответ был опубликованкто-то, но по какой-то причине был удален (очень хотелось бы, чтобы владелец оригинала ответа мог его опубликовать)