【发布时间】:2011-04-22 03:12:48
【问题描述】:
据我了解,在 Scala 中,我们可以通过在名称后使用空括号或根本不使用括号来定义不带参数的函数,这两个定义不是同义词。区分这两种语法的目的是什么?什么时候应该更好地使用一种而不是另一种?
【问题讨论】:
据我了解,在 Scala 中,我们可以通过在名称后使用空括号或根本不使用括号来定义不带参数的函数,这两个定义不是同义词。区分这两种语法的目的是什么?什么时候应该更好地使用一种而不是另一种?
【问题讨论】:
这主要是一个惯例问题。按照惯例,具有空参数列表的方法会评估其副作用。假设没有参数的方法没有副作用。这就是约定。
【讨论】:
def createAccount: Account 还是def createAccount(): Account?
method() 和 method 之间覆盖两种方式。您只能用另一个 val 覆盖 val,但是,method()() 被认为与 method() 和 method 不同(出于覆盖目的,但不用于名称冲突)。
Scala 风格指南说只有在被调用的方法没有副作用时才省略括号: http://docs.scala-lang.org/style/method-invocation.html
【讨论】:
其他答案很好,但我也认为值得一提的是,无参数方法可以很好地访问类字段,如下所示:
person.name
由于使用无参数方法,您可以轻松编写一个方法来拦截对“名称”字段的读取(或写入),而不会破坏调用代码,就像这样
def name = { log("Accessing name!"); _name }
【讨论】:
我对约定的有用性提出了另一个观点,该约定鼓励在函数声明中使用空括号块(因此稍后在调用它们时)会产生副作用。
调试器。
如果在调试器中添加一个监视,例如 process 指代焦点调试上下文中的布尔值的示例,或者作为变量视图,或者作为纯无副作用的函数评估,它为您以后的故障排除带来了严重的风险。
确实,如果调试器在您更改上下文(更改线程、在调用堆栈中移动、到达另一个断点...)时将该手表作为尝试评估的东西,我发现 IntelliJ 至少是这种情况IDEA 或其他语言的 Visual Studio,那么可能在任何浏览范围内找到的任何其他 process 函数的副作用都将被触发......
想象一下,如果您没有想到这个警告,可能会导致这种令人费解的故障排除,因为一些无辜的常规命名。如果按照我的示例强制执行约定,则process 布尔评估将永远不会退回到调试器监视中的process() 函数调用;它可能只允许在您的调试器中显式访问将 process() 放入手表的 () 函数,但很明显您没有直接访问任何属性或局部变量,而是回退到其他 process() 函数浏览过的范围,如果可能不走运,至少不会那么令人惊讶。
【讨论】: