Scala 函数没有通过带有大括号(大括号)的名称传递

Scala function not passed by name with curly brackets (braces)

我想按名称传递一个函数,在它执行之前做一些事情。考虑以下示例:

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 创建匿名 class。因此,在第二种情况下,语句 println("procedure!") 作为构造函数的一部分执行,但 apply() 未被调用,因此您只会看到

procedure!

作为输出。

自定义控件结构[​​=41=]

我想您打算使用第二条语句创建 custom control structure(尽管对于编译器而言,它是匿名的 class)。如果是这种情况,您可以使用以下语法:

val runner = new Runner()
runner.apply {println("procedure!")}
// OR simply 
runner {println("procedure!")} // this is possible because apply() is defined for Runner