Какое правило для круглых скобок при вызове метода Scala? - PullRequest
48 голосов
/ 10 июля 2011

Разве ToList не является методом, который преобразует что-то в список?

Если да, то почему я не могу использовать с ним круглые скобки?Я должен упустить что-то более фундаментальное.

Вот пример:

val l = Array(1,2,3).toList // works fine

val l = Array(1,2,3).toList() // gives the error below

Недостаточно аргументов для метода: (n: Int) Int в признаке LinearSeqOptimized.Не указано значение параметра n.

Ответы [ 3 ]

64 голосов
/ 10 июля 2011

Если метод определен как

def toList = { /* something */ }

тогда оно должно называться

object.toList

без лишних скобок. Мы говорим, что этот метод имеет списки нулевых параметров .

Мы также можем определить список параметров, но ничего не помещать в него:

def toList() = { /* something */ }

Теперь мы можем позвонить любому из

object.toList()
object.toList

, поскольку Scala позволяет использовать ярлыки для опускания скобок при вызовах методов.

Что касается JVM, то нет разницы между первым определением («списки нулевых параметров») и вторым («один пустой список параметров»). Но Скала проводит различие. Является ли это хорошая идея или нет, это вопрос спорный, но мотивация может быть яснее, когда вы понимаете, что мы можем также

def toList()() = { /* something */ }

, который известен как два пустых списка параметров , а затем вызвать любой из

object.toList()()
object.toList()
object.toList

и теперь, если бы мы преобразовали это в функцию, мы напечатали бы это как

() => () => T   /* T is the return value of the something */

в то время как второе определение будет

() => T

, что принципиально отличается концептуально, даже если вы используете его практически одинаково (ничего не вставляйте и рано или поздно вытащите T).

В любом случае, toList не нуждается в каких-либо параметрах, и стандарт Scala состоит в том, чтобы исключать паренсы, если только метод не изменяет сам объект (а не просто возвращает что-то), так что это def toList без паренсов впоследствии. И, таким образом, вы можете назвать это только как object.toList.

21 голосов
/ 11 июля 2011

Ваша вторая строка фактически интерпретируется как

val l = Array(1,2,3).toList.apply()

, поскольку foo(x) является "магическим" синтаксисом для foo.apply(x).

Вот почему компилятор жалуется на «недостаточно аргументов», поскольку метод apply для списков принимает один аргумент.

Таким образом, вы можете написать, например ::

scala> val i = Array(1, 2, 3).toList(1)
i: Int = 2
4 голосов
/ 28 августа 2013

Позвольте мне ответить с точки зрения стиля программирования Scala.

Scala руководство по стилю говорит ...

Пропустить пустые скобки, использовать только в том случае, если у рассматриваемого метода нет побочных эффектов (чисто функциональный). Другими словами, было бы приемлемо опустить круглые скобки при вызове queue.size, но не при вызове println ().

Религиозное соблюдение этого соглашения значительно улучшит читабельность кода и значительно упростит понимание самой основной операции любого данного метода. Не поддавайтесь искушению опустить скобки, просто чтобы сохранить два символа!

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