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>
考虑下面的代码(你可以直接在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>