2

考虑以下代码(您可以直接在Ideone上运行它):

object Main extends App {
  def foo[T](code: => T) : Runnable = new Runnable { def run = code }
  override def main(args: Array[String]): Unit = {
    val x: Runnable = foo(() => {
      System.out.println("b")
    })
    val y: Runnable = foo({
      System.out.println("d")
    })
    System.out.println("a")
    x.run()
    System.out.println("c")
    y.run()
    System.out.println("e")
  }
}

它打印a c d e,这意味着第一个 lambda 已成功传递给foo,但在我调用时未执行x.run()。但是,第二个已成功执行。

如果我删除包装Runnable并直接运行这些 lambda,它们都可以工作。我在使用 Java 库的 Scala 绑定时遇到了这种行为。

这里发生了什么?发生了什么x,为什么它有一些正确的值但什么也不做?

4

1 回答 1

3

Foo 的参数code是惰性的T(又名=> T)。

foo(System.out.println("d")),code是一个懒惰Unit的,因为那是println返回的。所以 runnable 会把惰性Unit变成实际的Unit.

而在foo(() => System.out.println("d")})code是个懒惰的人() => Unit。这意味着 runnable 正在将惰性() => Unit转换为实际() => Unit函数 - 但函数本身永远不会运行。

这是一个更简单的例子:

scala> def foo[T](code: => T) = code
foo: [T](code: => T)T

//`code` is evaluated to a `Unit`
scala> val x = foo(println("a"))
a
x: Unit = ()

//`code` is evaluated to a `() => Unit` function, but the function is never run
scala> val y = foo(() => println("a"))
y: () => Unit = <function0>
于 2015-07-10T07:25:12.357 回答