… нет, не говори мне, что тебе нравится Perl. Потому что ты не Вы никогда не делали. Это делает ужасные вещи. Это делает ваш код похожим на …
Разработка Perl 6, как можно найти на удивительной странице Perl Humor
Perl активно использовал перегрузку операторов и использовал операторы для разных целей. Аналогичная тенденция наблюдается в C ++ и Scala . Смотрите также людей, сравнивающих два . Так что не так с перегрузкой оператора?
Люди никогда не соглашались, правильно или неправильно перегружен оператор Scala:
Обычно люди ссылаются на обычных подозреваемых, таких как комплексные числа ( все получается правильно ):
class Complex(val real:Int, val imaginary:Int) { def +(operand:Complex):Complex = { new Complex(real + operand.real, imaginary + operand.imaginary) } def *(operand:Complex):Complex = { new Complex(real * operand.real - imaginary * operand.imaginary, real * operand.imaginary + imaginary * operand.real) } }
Вышеприведенное позволит теперь добавлять и умножать комплексные числа, и в этом нет абсолютно ничего плохого:
val c1 = new Complex(1, 2) val c2 = new Complex(2, -3) val c3 = c1 + c2 val res = c1 + c2 * c3
Но есть такие странные знаки препинания, которые просто сводят с ума обычных программистов:
-> ||= ++= <= _._ :: :+=
Не верь этому? Проверьте эту библиотеку графов !
На вышесказанное мы говорим:
Перегрузка оператора? Мех
Как должна быть перегрузка оператора
Перегрузка оператора может быть хорошей, но в основном это не так. В Java все мы упускаем лучшие способы взаимодействия с BigDecimal и аналогичными типами:
// How it is: bigdecimal1.add(bigdecimal2.multiply(bigdecimal3)); // How it should be: bigdecimal1 + bigdecimal2 * bigdecimal3
Конечно, приоритет оператора будет иметь место, как и ожидалось. В отличие от C ++ или Scala, идеальная перегрузка операторов просто отображает общие операторы на общие имена методов. Больше ничего. Никто не хочет, чтобы разработчики API придумали модных ##-%>>
операторов.
В то время как Ceylon , Groovy и Xtend реализовали это несколько предсказуемым и полезным способом, Kotlin , вероятно, является языком, который реализовал лучший стандартный механизм перегрузки операторов в их язык. Их документация гласит:
Бинарные операции
ЭКСПРЕССИЯ | Переведено на |
---|---|
а + б | a.plus (б) |
а — б | a.minus (б) |
а * б | a.times (б) |
а / б | a.div (б) |
% b | a.mod (б) |
a..b | a.rangeTo (б) |
Это выглядит довольно просто. Теперь проверьте это:
«Массив» доступ
СИМВОЛ | Переведено на |
---|---|
а [я] | a.get (я) |
a [i, j] | a.get (i, j) |
a [i_1, …, i_n] | a.get (i_1,…, i_n) |
a [i] = b | a.set (i, b) |
a [i, j] = b | a.set (i, j, b) |
a [i_1, …, i_n] = b | a.set (i_1,…, i_n, b) |
Теперь я действительно не вижу ни одного аргумента против вышесказанного. Это продолжается, и, к сожалению, Java 8 пропустила эту последовательность, так как ссылки на методы не могут быть назначены переменным и вызваны как функции JavaScript (хотя это не слишком поздно для Java 9+):
Вызовы метода
СИМВОЛ | Переведено на |
---|---|
а (я) | a.invoke (я) |
a (i, j) | a.invoke (i, j) |
a (i_1,…, i_n) | a.invoke (i_1,…, i_n) |
Просто красиво!
Вывод
Недавно мы писали об удивительных языковых особенностях Цейлона . Но вышеперечисленные возможности Kotlin, безусловно, убивают и устранят любые другие желания ввести перегрузку операторов в Java навсегда.
Будем надеяться, что будущие версии Java будут вдохновлены Kotlin, языком, который правильно перегрузил операторов.