Оставить подчеркивание в функции буквальным? - PullRequest
2 голосов
/ 24 февраля 2012
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 < _ } верно?

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

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

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

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

Ответы [ 3 ]

2 голосов
/ 24 февраля 2012

Причина этого в том, что 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 или что-то в этом роде.

1 голос
/ 25 февраля 2012

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

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

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

1 голос
/ 24 февраля 2012

То, что происходит, - это Расширение Eta (6.26.5):

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...