闭包中`lazy`类变量和`lazy`局部变量之间有什么区别?

时间:2013-07-14 18:09:19

标签: scala closures lazy-evaluation scalaz

object Need的Scalaz中我找到了

def apply[A](a: => A) = {
  lazy val value0: A = a
  new Need[A] {
    def value = value0
  }
}

这和(对我来说更自然)有什么区别

def apply[A](a: => A) = {
  new Need[A] {
    private lazy val value0: A = a
    def value = value0
  }
}

在性能,生成代码等方面?

1 个答案:

答案 0 :(得分:2)

在时间或空间关键应用中,您通常应该更喜欢第二种。原因是埋在字节码中。具体来说,如果我们有

abstract class Foo { def value: Int }
class Bar {
  def out(i: => Int) = {
    lazy val v0 = i
    new Foo { def value = v0 }
  }
  def in(i: => Int) = new Foo {
    private lazy val v0 = i
    def value = v0
  }
}

然后在第二种情况下,我们向字节码添加私有v0: Intbitmap$0: Boolean,以及标准的lazy val访问器。但是,在第一种情况下,我们会添加v0$lzy$1: runtime.IntRefbitmap$0$1: runtime.VolatileByteRef来引用在Int正文中创建的等效Booleanout方法。因此,我们有一层额外的包装。

在我的计算机上,out版本比in版本长约50%,以创建对象并检索value一次。