Confused о Scala методах вызова метода, в частности, о функции sum на Seq
Я играл с новой 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 со следующим сообщением:
недостаточно аргументов для суммы метода: (неявное число: числовое [B]) B. Неопределенный параметр значения параметра
В API Scala я вижу, что существует две версии sum, одна из которых не принимает никаких параметров, а другая - неявно. Нужно ли мне приводить методы без аргументов без круглых скобок?
Ответы
Ответ 1
Ответ заключается в том, что , если вы указываете список параметров (т.е. используете parens), , а вы должны указать параметры в нем ( или, точнее, те, которые не имеют значений по умолчанию).
Если вы опускаете парсеры в непустом списке параметров, параметры которого 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, чтобы показать вам, как использовать (иначе потенциально запутывающий) метод с неявным списком параметров. Существование этой записи в виде скалядока можно отнести к этому печально известному вопросу.
Ответ 2
Существует только одна версия. Если вы внимательно изучите API, запись, в которой нет скобок, говорит "[use case]" в начале. Это синтетическая двойная запись в документах API, которая упрощает захват; записи в прецедентах в основном сводятся к полной записи для некоторых распространенных сценариев. Подробнее об этом в этом вопросе: Scaladoc [use case]
Причина неудачи второго вызова (... sum()) заключается в том, что хотя аргумент неявный, он не имеет значения по умолчанию. Вы можете только пропустить аргументы в круглых скобках, если указаны значения по умолчанию. Хотя это звучит нелогично, неявные аргументы обрабатываются по-разному: либо вы предоставляете их явно, то вам нужно использовать круглые скобки, или вы их опускаете (потому что имплицитный найден в области), но тогда вам также нужно отбросить круглые скобки. Это должно облегчить читаемость, например.
def test(fun: Int => Int)(implicit s: String)
теперь вы можете написать test { i => i }
, а не test(i => i)()
, что неудобно.