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

Tra*_*ago 49 scala

是不是要列出一个将某些内容转换为List的方法?

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

这是一个例子:

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

val l = Array(1,2,3).toList() // gives the error below
Run Code Online (Sandbox Code Playgroud)

方法适用的参数不足:(n:Int)特征LinearSeqOptimized中的Int.未指定的值参数n.

Rex*_*err 65

如果方法定义为

def toList = { /* something */ }
Run Code Online (Sandbox Code Playgroud)

然后它必须被称为

object.toList
Run Code Online (Sandbox Code Playgroud)

没有额外的括号.我们说这个方法没有参数列表.

我们还可以定义一个参数列表,但不加任何内容:

def toList() = { /* something */ }
Run Code Online (Sandbox Code Playgroud)

现在,我们可以打电话给任何一个

object.toList()
object.toList
Run Code Online (Sandbox Code Playgroud)

因为Scala允许在方法调用上省略括号的快捷方式.

就JVM而言,第一个定义("零参数列表")和第二个定义("一个空参数列表")之间没有区别.但Scala保持着区分.这是否是一个好主意是有争议的,但当你意识到我们也可以时,动机可能更清晰

def toList()() = { /* something */ }
Run Code Online (Sandbox Code Playgroud)

这被称为两个空参数列表,然后调用任何一个

object.toList()()
object.toList()
object.toList
Run Code Online (Sandbox Code Playgroud)

现在,如果我们将其转换为函数,我们将其键入

() => () => T   /* T is the return value of the something */
Run Code Online (Sandbox Code Playgroud)

而第二个定义是

() => T
Run Code Online (Sandbox Code Playgroud)

这在概念上是明显不同的,即使实际上你以相同的方式使用它(什么也不做,迟早会出来T).

无论如何,toList不需要任何参数,并且Scala标准是除非方法改变对象本身(而不仅仅是返回某些东西),否则def toList不要使用parens ,所以之后没有任何parens.因此你只能称之为object.toList.

  • 你忘了提到额外的括号会产生错误,因为它被认为是生成的`List`的`apply`方法. (7认同)

Knu*_*daa 21

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

val l = Array(1,2,3).toList.apply()
Run Code Online (Sandbox Code Playgroud)

因为foo(x)是"魔术"的语法foo.apply(x).

这就是为什么编译器抱怨"没有足够的参数",因为列表上的apply方法需要一个参数.

因此你可以写例如:

scala> val i = Array(1, 2, 3).toList(1)
i: Int = 2
Run Code Online (Sandbox Code Playgroud)


Vis*_*ohn 5

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

Scala风格指南说...

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

虔诚地遵守这个约定将大大提高代码的可读性,并使任何给定方法的最基本操作一目了然地更容易理解。抵制只是为了保存两个字符而省略括号的冲动!