Scala方法调用中括号的规则是啥?
Posted
技术标签:
【中文标题】Scala方法调用中括号的规则是啥?【英文标题】:What is the rule for parenthesis in Scala method invocation?Scala方法调用中括号的规则是什么? 【发布时间】:2011-07-10 18:29:01 【问题描述】:toList 不就是将某物转化为 List 的方法吗?
如果是,那为什么我不能用括号呢?我一定在这里遗漏了一些更基本的东西。
示例如下:
val l = Array(1,2,3).toList // works fine
val l = Array(1,2,3).toList() // gives the error below
方法 apply 的参数不足:(n: Int)Int in trait 线性序列优化。未指定值参数n。
【问题讨论】:
在这里找到了一个类似的问题,可能会有所帮助:Confused about Scala method calling conventions, specifically the sum function on Seq 【参考方案1】:如果一个方法被定义为
def toList = /* something */
那么它必须被称为
object.toList
没有额外的括号。我们说这个方法有零个参数列表。
我们也可以定义一个参数列表,但什么都不放:
def toList() = /* something */
现在,我们可以调用任何一个
object.toList()
object.toList
因为 Scala 允许在方法调用中省略括号。
就JVM而言,第一个定义(“零参数列表”)和第二个定义(“一个空参数列表”)没有区别。但 Scala 保持着一种区别。这是否是一个好主意值得商榷,但当你意识到我们也可以时,动机可能会更清楚
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
。
【讨论】:
你的解释很棒。我很难想象 toList()() 的目的,但我现在会相信 scala... 你忘了提到额外的括号会产生错误,因为它被认为是结果List
的 apply
方法。
@JeffLee - 不,(,)
是无效的语法。 ()()
是两个空参数列表(只有 Scala 知道;对于其他任何东西,它看起来就像一个没有参数的方法)。
@JeffLee - 你是说(a: Int, b: Int)
还是(a: Int)(b: Int)
?这些对于 Scala 也不相同:一个有一个带有两个参数的参数列表,而另一个有两个带有一个参数的参数列表。 (但在字节码中,它们的实现方式相同;JVM 不知道多个参数列表。)
@JeffLee - Scala 库广泛使用该功能来进行隐式,并使事物看起来像语言的内置方面。例如,list.foldLeft(0) (sum, x) => sum + x
使用两个参数列表定义(您将初始值和将另一个列表元素合并到结果中的函数放入其中)。【参考方案2】:
您的第二行实际上被解释为
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
【讨论】:
也许这就是为什么如果方法没有参数,最好不要声明它。然后你可以像上面一样使用“链接”。 但同时很难判断 (1) 是方法的参数还是要应用于方法结果。 :-|【参考方案3】:让我从 Scala 编码风格的角度来回答。
Scala style guide 说...
省略空括号,仅在所讨论的方法没有副作用(纯功能)时使用。换句话说,在调用 queue.size 时省略括号是可以接受的,但在调用 println() 时则不行。
虔诚地遵守此约定将显着提高代码的可读性,并使任何给定方法的最基本操作一目了然。忍住为了节省两个字符而省略括号的冲动!
【讨论】:
以上是关于Scala方法调用中括号的规则是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Scala中调用函数或者方法为啥有时候需要括号,有时候不需要括号