在Scala方法调用中,括号的规则是什么?
在Scala的方法调用中,括号的规则是:当方法没有副作用(纯函数式)时可以省略括号,否则需要使用括号。遵循这个规则可以大大提高代码的可读性,让人一眼就能理解给定方法的最基本操作。不要仅仅为了节省两个字符而省略括号。
该问题的出现原因是因为在Scala中,方法的调用可以使用括号,也可以不使用括号,这可能会导致代码的可读性和一致性问题。有些人可能会倾向于省略括号以简化代码,但这可能会使代码更难以理解。因此,Scala的编码风格指南建议在方法没有副作用时可以省略括号,但有副作用时需要使用括号。
解决方法是遵循Scala的编码风格指南,在方法没有副作用时可以省略括号,但有副作用时需要使用括号。这样可以提高代码的可读性,并保持代码的一致性。在编写代码时,应该根据方法是否有副作用来决定是否使用括号。如果方法具有副作用,则应该使用括号来明确指示该方法会改变程序状态。如果方法没有副作用,则可以省略括号以简化代码。
下面是一个示例代码,展示了在Scala中如何使用括号来调用方法:
val queue = new Queue[Int] // 使用括号调用没有副作用的方法 val size = queue.size() // 使用括号调用有副作用的方法 println("Hello, World!")
在上面的代码中,`size()`方法没有副作用,因此使用了括号来调用。而`println()`方法有副作用,因此也使用了括号来调用。遵循这样的规则可以提高代码的可读性和一致性。
Scala方法调用中括号的规则是什么?
在Scala中,如果一个方法定义为:
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是something的返回值 */
而第二个定义将是:
() => T
这在概念上显然是不同的,即使在实际上你以相同的方式使用它(不放入任何内容,最终获得一个T
)。
无论如何,toList
不需要任何参数,而且Scala的标准是在没有改变对象本身的方法(而只是返回某些东西)时省略括号,所以它是def toList
,后面没有任何括号。因此,只能以object.toList
的方式调用它。
你的解释很好。很难想象toList()()
的用途,但我现在会相信Scala...
你忘记提到额外的括号会导致错误,因为它被认为是结果List
的apply
方法。
- 说得好。但是,如果没有apply
,我们总是可以回到忽略括号的方式,所以这个解释并不能完全解决问题。我会让人们阅读你的评论以了解更多解释 🙂
在函数中,(,)
和()()
是否相同?
- 不,(,)
是无效的语法。()()
表示两个空参数列表(只有Scala知道;对于其他任何东西,它只是一个没有参数的方法)。
其中有一个def addInt( a:Int, b:Int ) : Int
。
- 你是不是指(a: Int, b: Int)
和(a: Int)(b: Int)
?对于Scala来说,它们也不相同:一个有两个参数的参数列表,而另一个有两个参数列表,每个参数列表都有一个参数(在字节码中,它们的实现方式相同;JVM没有多个参数列表的概念)。
- Scala库广泛使用这个特性来实现隐式转换和使事物看起来像是语言的内置方面。例如,list.foldLeft(0){ (sum, x) => sum + x }
定义了两个参数列表(用于放置初始值和将另一个列表元素合并到结果中的函数)。
这种技术称为柯里化。当你没有所有参数时,它也非常有用。比如,你可以有类似sendMessage(msg: String)(timeout: Int)
的方法。然后,你可以调用val sendMessage1sTimeout = sendMessage(1000)
并获得一个总是在1000毫秒后超时的方法。然后,你可以调用sendMessage1sTimeout("hello")
和sendMessage1sTimeout("bye!")
。这在参数始终相同的情况下特别有用,或者如果你的参数在不同的位置或执行点找到。