Scala 函数不按名称用大括号(大括号)传递

标签 scala pass-by-name

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

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/

相关文章:

scala - Scala 按名称参数的使用

r - 如果我只知道字符串形式的对象名称,如何覆盖 R 中的对象?

scala - 如何多次调用 `flatMap`? - 类似 FP 的方式

Scala 隐式参数被编译器标记为未使用

json - 找不到play.api.libs.json.JsObject类型的Json序列化程序作为JsObject

java - 为什么 Scala 不在这里保留字段注释?

java - 集合排序抛出异常

scala - 构造函数的按名称参数