Scala 方法调用中括号的规则是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6643030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the rule for parenthesis in Scala method invocation?
提问by TraderJoeChicago
Isn't toList a method that converts something into a List?
toList 不是将某些内容转换为 List 的方法吗?
If yes so why can't I use parenthesis with it? I must be missing something more fundamental here.
如果是,那么为什么我不能使用括号呢?我一定在这里遗漏了一些更基本的东西。
Here is the example:
这是示例:
val l = Array(1,2,3).toList // works fine
val l = Array(1,2,3).toList() // gives the error below
Not enough arguments for method apply: (n: Int)Int in trait LinearSeqOptimized. Unspecified value parameter n.
方法的参数不足:(n: Int)Int in trait LinearSeqOptimized。未指定值参数 n。
回答by Rex Kerr
If a method is defined as
如果一个方法被定义为
def toList = { /* something */ }
then it must be called as
那么它必须被称为
object.toList
with no extra parentheses. We say that this method has zero parameter lists.
没有额外的括号。我们说这个方法有零个参数列表。
We could also define a parameter list but put nothing in it:
我们也可以定义一个参数列表,但什么都不放在里面:
def toList() = { /* something */ }
Now, we could call either of
现在,我们可以调用
object.toList()
object.toList
since Scala allows the shortcut of omitting parentheses on method calls.
因为 Scala 允许在方法调用中省略括号的快捷方式。
As far as the JVM is concerned, there is no difference between the first definition ("zero parameter lists") and the second ("one empty parameter list"). But Scala maintains a distinction. Whether this is a good idea or not is debatable, but the motivation might be clearer when you realize that we can also
就 JVM 而言,第一个定义(“零参数列表”)和第二个(“一个空参数列表”)之间没有区别。但是 Scala 保持着区别。这是否是一个好主意值得商榷,但当你意识到我们也可以
def toList()() = { /* something */ }
which is known as two empty parameter lists, and then call any of
这被称为两个空参数列表,然后调用任何
object.toList()()
object.toList()
object.toList
and now, if we were to convert this into a function, we would type it as
现在,如果我们要把它转换成一个函数,我们可以把它写成
() => () => T /* T is the return value of the something */
while the second definition would be
而第二个定义是
() => T
which is clearly different conceptually, even if practically you use it the same way (put in nothing and sooner or later get out a T).
这在概念上显然是不同的,即使实际上您以相同的方式使用它(什么也不放,迟早会退出 a T)。
Anyway, toListdoesn't need any parameters, and the Scala standard is to leave off the parens unless the method changes the object itself (rather than just returning something), so it's def toListwithout any parens afterwards. And thus you can only call it as object.toList.
无论如何,toList不需要任何参数,Scala 标准是不使用括号,除非方法更改对象本身(而不是仅仅返回某些内容),因此def toList之后没有任何括号。因此,您只能将其称为object.toList.
回答by Knut Arne Vedaa
Your second line is actually interpreted as
你的第二行实际上被解释为
val l = Array(1,2,3).toList.apply()
since foo(x)is "magic" syntax for foo.apply(x).
因为foo(x)是foo.apply(x).
That's why the complier complains about "not enough arguments", as the apply method on lists takes one argument.
这就是为什么编译器抱怨“没有足够的参数”,因为列表上的 apply 方法需要一个参数。
Thus you can write e.g.:
因此你可以写例如:
scala> val i = Array(1, 2, 3).toList(1)
i: Int = 2
回答by Vishal John
Let me answer from Scala coding style perspective.
让我从 Scala 编码风格的角度来回答。
Scala style guidesays...
Scala风格指南说...
Omit empty parenthesis, only be used when the method in question has no side-effects (purely-functional). In other words, it would be acceptable to omit parentheses when calling queue.size, but not when calling println().
省略空括号,仅在所讨论的方法没有副作用(纯函数式)时使用。换句话说,在调用 queue.size 时省略括号是可以接受的,但在调用 println() 时则不能。
Religiously observing this convention will dramatically improve code readability and will make it much easier to understand at a glance the most basic operation of any given method. Resist the urge to omit parentheses simply to save two characters!
虔诚地遵守这个约定将大大提高代码的可读性,并使任何给定方法的最基本操作一目了然地更容易理解。抵制为了节省两个字符而省略括号的冲动!

