Подтвердить что ты не робот

Оператор тильды в Scala

Что делает ~ в этом бите Scala?

Например:

scala> val apple = 1
apple: Int = 1

scala> ~apple
res0: Int = -2

Что сделал этот червь с моим яблоком?

4b9b3361

Ответ 1

Во-первых, некоторые мета-советы. Каждый раз, когда вам интересно, как компилятор расширяет синтаксический сахар, вводит тип или применяет неявное преобразование, используйте scala -Xprint:typer -e <expr>, чтобы показать вам, что произошло.

scala -Xprint:typer -e "val a = 2; ~a"

...
private[this] val a: Int = 2;
private <stable> <accessor> def a: Int = $anon.this.a;
$anon.this.a.unary_~

Хорошо, префикс ~ расширяется до регулярного вызова метода unary_~.

Из спецификации :

6.12.1 Предварительные операции

Предварительная операция op e состоит из pre fi x operator op, который должен быть одним из идентификаторов +, -, ! или ~. Выражение op e эквивалентно приложению постфиксного метода e.unary_op.

Операторы pre fi x отличаются от обычных приложений функций что их выражение операндов не должно быть атомарным. Например, входная последовательность -sin(x) считывается как -(sin(x)), тогда как функция application negate sin(x) будет анализироваться как применение в fi x operator sin для операндов отрицать и (x).

Это означает, что операторы префикса не ограничены встроенными типами, они могут использоваться на ваших собственных типах (хотя это не является хорошей идеей сходить с ума от этой силы!)

scala> object foo { def unary_~ = "!!!" }
defined module foo

scala> ~foo
res0: java.lang.String = !!!

Итак, как насчет вашего вопроса? Вы можете проверить индекс ScalaDoc для стандартной библиотеки для методов начиная с u. ночной ScalaDoc недавно добавила документацию для этого метода.

the bitwise negation of this value
Example:
~5 == -6
// in binary: ~00000101 ==
//             11111010

Ответ 2

~ является побитовым оператором, когда применяется к целым числам. Проще всего видеть в шестнадцатеричном виде:

scala> "%x".format( ~0x7F )
res0: String = ffffff80