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

问题描述 投票:31回答:1

有几次我看到像这样的Scala代码:

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

以这种方式调用:

Doer.doStuff{
      println("Done")
}

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

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

scala syntax
1个回答
46
投票

这被称为nullary函数或thunk,并且是按名称评估的示例:http://www.scala-lang.org/old/node/138

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

所以

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

与以下内容完全相同:

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

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

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

将两次打印“foo”。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.