Оставить подчеркивание в функции буквальным?

scala> val alist = List(1,2,3,4,5)
alist: List[Int] = List(1, 2, 3, 4, 5)

scala> alist filter { 2.< }
res2: List[Int] = List(3, 4, 5)

scala> alist filter { 2 < }
res3: List[Int] = List(3, 4, 5)

scala> alist filter { > 3 }
<console>:1: error: ';' expected but integer literal found.
       alist filter { > 3 }

Почему бы { 2.< } а также {2 <} Работа? Я думаю, по крайней мере, я должен написать { 2 < _ } право?

Метод, который не требует аргументов, вы также можете оставить точку и использовать нотацию постфиксного оператора:

scala> val s = "Hello, world!"
s: java.lang.String = Hello, world!
scala> s toLowerCase
res4: java.lang.String = hello, world!

Но здесь, < Метод это не те методы, которые не требуют аргументов, верно?

Можете ли вы указать мне, что это за использование?

3 ответа

Решение

Происходит расширение Eta (6.26.5):

Эта-расширение преобразует выражение типа метода в эквивалентное выражение типа функции.

В этом случае, 2 < это тип метода: (один из) метод < на Int, Тем не мение, filter ожидает тип функции. В таком случае Scala выполняет автоматическое расширение eta.

Обратите внимание, что, поскольку тип, ожидаемый filter известно, что он может правильно сделать вывод, что 2 < метод вызывается.

Причина этого в том, что 2 это объект, так что если вы пишете 2.< или же 2 < (которые на самом деле одинаковы в Scala), то вы вызываете метод < на объекте 2,

Если вы просто напишите < или же > Компилятор будет искать такой метод в локальной области, но не найдет его. Точно так же, написание > 3, компилятору нужен метод > доступно, чего нет.

Вы также можете увидеть это поведение непосредственно в консоли:

scala> 3.<
<console>:8: error: ambiguous reference to overloaded definition,
both method < in class Double of type (x: Char)Boolean
and  method < in class Double of type (x: Short)Boolean
match expected type ?
               3.<
                 ^

Как вы можете видеть, есть несколько определенных последствий, которые превращают 3 в объект класса, который определяет < метод. Так что это работает в принципе, но не может стоять самостоятельно. Это работает, однако, если у вас есть больше информации о типе, как в вашем примере.

Сравните это со следующим:

scala> <(3)
<console>:8: error: not found: value <
              <(3)
              ^

Здесь вы можете увидеть компилятор, ищущий автономный < где-то. Обратите внимание, что в сообщении об ошибке указано значение, но это все равно означает, что это может быть функция, так как тип значения может быть (Int, Int) => Boolean или что-то типа того.

2.< относится к методу < объекта 2, в то время как 2.<(_) возвращает новую функцию с одним аргументом. Последний является сокращением для (расширен до) (x: Int) => 2 < x где тип Int был выведен компилятором Scala из типа элементов alist,

> 3 в вашем случае не ссылается на какой-либо метод или объект какого-либо объекта. > является допустимым идентификатором scala (для метода, функции или объекта), но 3 не является юридическим идентификатором (начинается с цифры). > a может быть ссылкой на член a объекта > (>.a). Но ни один из них не существует в вашем примере. _ > 3 однако возвращает новую функцию с одним аргументом, который вы также можете написать (x: Int) => x > 3,

По сути, это то же самое, что ответ Даниэля С. Собрала и комментарий к ответу Фрэнка, но менее формальный и с большим количеством примеров. Надеюсь, что это помогает получить интуицию.

Другие вопросы по тегам