Ответ 1
Префикс unary_
для унарных префиксных операторов немного вводит в заблуждение: это больше о префиксной части, чем одинарная часть. Вам нужно каким-то образом отличить
!foo // unary prefix !
из
foo! // unary postfix !
Помните: Scala фактически не имеет операторов. Существует два способа вызова метода с помощью .
или с пробелом:
foo.bar(1, "two")
foo bar(1, "two")
И когда у вас есть один аргумент, вы можете оставить круглые скобки:
foo plus(1)
foo plus 1
Наконец, (почти) любой символ является законным в идентификаторе:
foo plus 1
foo + 1
Теперь похоже, что Scala имеет двоичный инфикс +
, но на самом деле это не так. Это просто обычный метод, вызванный с помощью обычного синтаксиса вызова метода.
Однако, что я сказал выше, не совсем верно. Если Scala не поддерживала операторов, и все это был обычный вызов метода, тогда
2 + 3 * 4
будет оцениваться до 20 (например, в Smalltalk, Self и Newspeak, например) вместо 14. Таким образом, есть немного поддержки для операторов в Scala (на самом деле два маленьких бита). Когда метод вызывается с пробелом (так называемый "синтаксис оператора" ) вместо .
, и этот метод начинается с символа оператора, тогда Scala будет соблюдать приоритет оператора.
И другая небольшая поддержка оператора - это то, что есть некоторые операторы, которые вы хотели бы иметь, но это не может быть легко выражено как вызов метода. Он отлично работает для двоичных инфиксных операторов и унарных операторов постфикса:
foo op bar // same as:
foo.op(bar)
foo op // same as:
foo.op
Но не для операторов префикса или "around-fix":
!foo
foo(bar)
Итак, существует несколько специальных правил синтаксического перевода сахара:
!foo
foo.unary_!
// same for +, - and ~
foo(bar)
foo.apply(bar)
foo(bar) = 1
foo.update(bar, 1)
foo += 1
foo.+=(1) // but if this doesn't compile, then the compiler will also try
foo = foo.+(1)
И причина, по которой должно быть подчеркивание между буквенно-цифровой и "операторной" частью в имени метода, заключается в том, что вы не знаете,
foo!
означает
foo.!
или
this.foo!
Таким образом, foo!
как имя метода является незаконным, его нужно называть foo_!
.