Scala方法调用中括号的规则是什么?

时间:2011-07-10 18:29:02

标签: scala

是不是要将某个东西转换为List的方法?

如果是,那么为什么我不能用括号呢?我必须在这里遗漏一些更基本的东西。

以下是示例:

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 个答案:

答案 0 :(得分:63)

如果方法定义为

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标准是除非方法改变对象本身(而不仅仅是返回一些东西),否则它会离开parens,所以它是def toList没有之后的任何事件。因此,您只能将其称为object.toList

答案 1 :(得分:21)

您的第二行实际上被解释为

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

答案 2 :(得分:4)

让我从Scala编码风格的角度回答。

Scala style guide说......

省略空括号,仅在有问题的方法没有副作用(纯函数)时使用。换句话说,在调用queue.size时省略括号是可以接受的,但在调用println()时则不行。

宗教观察此惯例将极大地提高代码的可读性,并使一目了然的任何给定方法的最基本操作更容易理解。只需保存两个字符就可以抵制省略括号的冲动!