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は、最初のラムダが に正常に渡されfooたが、 を呼び出したときに実行されなかったことを意味しますx.run()。ただし、2 つ目は正常に実行されます。

そのラッピングを削除してRunnableこれらのラムダを直接実行すると、両方とも機能します。Java ライブラリの Scala バインディングを使用していたときに、この動作に遭遇しました。

ここで何が起こっているのですか?に何が起こったxのですか。正しい値があるのに何もしないのはなぜですか?

4

1 に答える 1

3

Foo のパラメーターcodeは遅延T(別名=> T) です。

ではfoo(System.out.println("d"))、それが返されるためcode、怠け者です。そのため、ランナブルはその怠惰を実際の に変えます。UnitprintlnUnitUnit

一方foo(() => System.out.println("d")})codeは怠け者() => Unitです。つまり、ランナブルが遅延() => 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 に答える