将函数作为花括号之间的代码块传递

时间:2014-03-26 18:47:04

标签: scala syntax

有几次我看到了类似的Scala代码:

object Doer{
   def doStuff(op: => Unit) {
      op
   }
}

以这种方式调用:

Doer.doStuff{
      println("Done")
}

对我来说,奇怪的是函数如何作为花括号之间的代码块传递给另一个函数。甚至没有括号通常标记参数列表的开头和结尾。

此Scala语法/功能的名称是什么?在什么情况下我可以使用它?它在哪里记录?

1 个答案:

答案 0 :(得分:43)

这称为 nullary function thunk ,是按名称评估的示例:{{3 }}

你可以在任何有参数列表的地方使用nullaries。它们基本上只是零参数函数的语法糖,使它们看起来像普通值,并且只要它们被引用就会被调用。

所以

def doSomething(op: => Unit) {
  op
}
doSomething {
  println("Hello!")
}

与:

完全相同
def doSomething(op: () => Unit) {
  op()
}
doSomething(() => println("Hello!"))

要记住这些事情的一件事是每次引用它们时都会调用它们,所以类似于:

def foo(op: => Int) = op + op
foo {
  println("foo")
  5
}

将打印" foo"两次。

编辑:为了扩展Randall的评论,nullary函数与zero-arg函数不同的一个重要方法是nullaries不是一等值。例如,您可以拥有List[() => Int],但不能拥有List[=> Int]。如果你有类似的东西:

def foo(i: => Int) = List(i)

您没有将nullary函数添加到列表中,只是它的返回值。