Scala:lambda 被传递给一个函数,被包装到 Runnable 中并且之后没有被执行 - 这是怎么回事?

Scala: lambda is passed to a function, gets wrapped into Runnable and does not get executed afterwards - what is going on?

考虑下面的代码(你可以直接在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 发生了什么,为什么它有一些正确的值但什么都不做?

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

foo(System.out.println("d"))中,code是一个懒惰的Unit,因为那是println returns。所以 运行nable 会将懒惰的 Unit 变成实际的 Unit.

而在 foo(() => System.out.println("d")}) 中,code 是一个懒惰的 () => Unit。这意味着 运行nable 正在将惰性 () => 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>