如果我们可以不使用括号来定义不需要任何参数的函数,为什么在Scala中使用空括号?

时间:2010-10-07 00:49:06

标签: scala function syntax

据我所知,在Scala中,我们可以通过在其名称后面使用空括号来定义一个没有参数的函数,或者根本不使用括号,这两个定义不是同义词。区分这两种语法的目的是什么?何时应该更好地使用一种语法而不是另一种?

4 个答案:

答案 0 :(得分:38)

这主要是一个常规问题。按照惯例,使用空参数列表的方法评估其副作用。假设没有参数的方法是无副作用的。这就是惯例。

答案 1 :(得分:11)

Scala样式指南说只有当被调用的方法没有副作用时才省略括号: http://docs.scala-lang.org/style/method-invocation.html

答案 2 :(得分:1)

其他答案很棒,但我也认为值得一提的是,no-param方法可以很方便地访问类字段,如下所示:

person.name

由于无参数方法,您可以轻松编写一种方法来拦截对“名称”字段的读取(或写入),而不会破坏调用代码,如此

def name = { log("Accessing name!"); _name }

这称为Uniform Access Principal

答案 3 :(得分:0)

我还有另一个亮点,即公约的有用性,鼓励在函数声明中使用空括号块(因此稍后调用它们)会产生副作用。

使用 调试程序

如果在调试器中添加一个监视器,例如,\documentclass{article} \usepackage{booktabs} \begin{document} <<>>= library(knitr) dat <- mtcars[1:5,1:5] options(knitr.table.format = "latex") @ <<results='asis'>>= names(dat)[1] <- "$x^2$" kable(dat, booktabs=TRUE, caption="My table") @ \end{document} 将该示例引用到聚焦调试上下文中的布尔值,则作为变量视图或纯副作用自由函数评估,它为您以后的故障排除带来了巨大的风险。 实际上,如果调试器在每次更改上下文(更改线程,移入调用堆栈,到达另一个断点......)时将该监视作为尝试评估的东西,我发现至少是IntelliJ的情况IDEA或其他语言的Visual Studio,可能会触发任何浏览范围内任何其他process函数的副作用......

想象一下这种令人费解的故障排​​除,如果你没有记住这个警告,可能会因为一些无辜的常规命名而导致这种警告。如果强制执行约定,我的示例中,process布尔值评估将永远不会回退到调试器监视中的process函数调用;它可能只允许在你的调试器中显式访问将process()放在监视器中的()函数,但是很明显你不是直接访问任何属性或局部变量,而是回退到其他{{1}在其他浏览范围中的函数,如果可能不吉利,至少会非常不令人惊讶。