Запутался в соглашениях о вызовах методов Scala, в частности в функции сумм на Seq - PullRequest
15 голосов
/ 05 апреля 2011

Я играл с новой Scala IDE (Eclipse 3.6.2 + Scala IDE 2.0.0 [Scala 2.9.0]) и пытался сделать что-то простое, как это:

(1 to 10).sum

Это прекрасно работает, но я недавно много занимался Groovy и автоматически написал:

(1 to 10).sum()

Эта вторая версия дает мне ошибку компилятора в IDE со следующим сообщением:

недостаточно аргументов для метода sum: (неявный num: Numeric [B]) B. Не указано значение параметра num.

Я вижу в Scala API, что есть две версии суммы: одна, которая не принимает параметров, и другая, которая принимает неявное выше. Нужно ли вызывать методы без аргументов без скобок?

Ответы [ 2 ]

25 голосов
/ 05 апреля 2011

Ответ таков: , если вы указываете список параметров (то есть используете парены), затем вы должны указать параметры в нем (или, точнее, без значений по умолчанию).

Если вы опустите парены в непустом списке параметров, параметры которого implicit, то компилятор может внедрить их для вас (при условии, что он сможет однозначно найти соответствующие последствия в вашей области видимости: как в вашем первом примере)

1 to 10 sum

Если вы хотите передать параметр самостоятельно (в этом примере это делать не нужно), вы можете воспользоваться Predef.implicitly, который в основном возвращает однозначное неявное значение в области (при условии, что оно есть) , Их использование здесь будет:

(1 to 10).sum(implicitly[Numeric[Int]])
(1 to 10).sum[Int](implicitly)

Это особенно важно в методах, которые принимают более одного неявного параметра, из которых вы можете переопределить только один (затем вы можете использовать implicitly для других). Например, в scalaz

aFoldable.sum(implicitly, myMonoid) //uses implicit Foldable but bespoke monoid

На ваш вопрос о scaladoc прецедент ; это запись phantom , показывающая, как использовать (в противном случае потенциально запутанный) метод со списком неявных параметров. Существование этой записи в скаладоке можно проследить до этого пресловутого вопроса .

3 голосов
/ 05 апреля 2011

Есть только одна версия.Если вы внимательно посмотрите на API, запись, которая не содержит скобок, в начале говорит «[вариант использования]».Это искусственная дублирующая запись в документах API, которая облегчает понимание;Записи прецедентов в основном являются сокращенными полными записями для некоторых распространенных сценариев.Подробнее об этом в этом вопросе: Scaladoc [вариант использования]

Причина, по которой второй вызов (... sum ()) завершается неудачей, заключается в том, что хотя аргумент неявный, он не 'не может иметь значение по умолчанию.Вы можете опустить аргументы в скобках, только если указаны значения по умолчанию.Хотя это звучит нелогично, неявные аргументы обрабатываются по-разному: либо вы предоставляете их явно, либо вам нужно использовать круглые скобки, либо вы их опускаете (поскольку неявный находится в области видимости), но тогда вам также необходимо удалить скобки.Это сделано для улучшения читабельности, например,

def test(fun: Int => Int)(implicit s: String)

теперь вы можете написать test { i => i }, а не test(i => i)(), что неудобно.

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