【问题标题】:Scala function not passed by name with curly brackets (braces)Scala 函数未使用大括号(大括号)按名称传递
【发布时间】:2016-08-13 05:11:31
【问题描述】:

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

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!

被打印出来了。

似乎在使用花括号时,过程不是按名称传递而是执行。 为什么在这个例子中大括号和圆括号不能互换?

【问题讨论】:

    标签: scala pass-by-name


    【解决方案1】:

    第一句话:

    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
    

    【讨论】:

    • 对,我没有看到新的匿名类语法。现在它是有道理的。不过,这有点令人困惑,圆括号和大括号不能互换。
    猜你喜欢
    • 2015-03-04
    • 2013-01-17
    • 2015-06-29
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多