我想按名称传递一个函数,在它执行之前做一些事情。考虑以下示例:
class Runner {
def apply(procedure: => Unit) = {
println("running procedure")
procedure
}
}
new Runner()(println("procedure!")) // #1
new Runner(){println("procedure!")} // #2
调用 #1 和 #2 之间的唯一区别在于花括号。虽然第一个调用输出
running procedure
procedure!
正如预期的那样,仅在第二次通话中
procedure!
被打印。
似乎当使用大括号时,过程不是按名称传递而是执行。 为什么在这个例子中大括号和圆括号不能互换?
最佳答案
第一条语句:
new Runner()(println("procedure!")) // #1
在第一种情况下,当使用括号时,会调用
apply()
方法并将 println("procedure!")
作为参数传递。所以第一条语句等价于:new Runner().apply(println("procedure!"))
因此输出是:
running procedure
procedure!
第二条语句:
new Runner(){println("procedure!")} // #2
在第二种情况下,您通过扩展
Runner
创建一个匿名类。所以在第二种情况下,println("procedure!")
作为构造函数的一部分执行,但 apply()
没有被调用,因此你只能看到procedure!
作为输出。
自定义控制结构
我想您打算使用第二个语句创建 custom control structure (尽管对于编译器,它是一个匿名类)。如果是这种情况,您可以使用以下语法:
val runner = new Runner()
runner.apply {println("procedure!")}
// OR simply
runner {println("procedure!")} // this is possible because apply() is defined for Runner
关于Scala 函数不按名称用大括号(大括号)传递,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36745232/