Scala的本地惰性变量是如何实现的?
发布时间:2020-12-16 18:35:32 所属栏目:安全 来源:网络整理
导读:有一个 question询问lazy vals的实现,如果它们是类变量的话.如何实现局部变量,例如 def foo[A](a: = A) = { lazy val x: A = a // return something that uses x} 解决方法 在方法中使用惰性val的效率稍差.原因是你实际上不能嵌套函数,所以名义上在堆栈上分
有一个
question询问lazy vals的实现,如果它们是类变量的话.如何实现局部变量,例如
def foo[A](a: => A) = { lazy val x: A = a // return something that uses x } 解决方法
在方法中使用惰性val的效率稍差.原因是你实际上不能嵌套函数,所以名义上在堆栈上分配的惰性位实际上需要在堆上.所以你必须创建至少一个额外的对象,事实证明Scala实际上创建了两个.
class Baz{ def baz(i: => Int,b: Boolean) = { lazy val j = i if (b) j else 0 } } 除其他外,变成了 public int baz(scala.Function0,boolean); Code: 0: new #12; //class scala/runtime/IntRef 3: dup 4: iconst_0 5: invokespecial #16; //Method scala/runtime/IntRef."<init>":(I)V 8: astore_3 9: new #18; //class scala/runtime/VolatileByteRef 12: dup 13: iconst_0 14: invokespecial #21; //Method scala/runtime/VolatileByteRef."<init>":(B)V 17: astore 4 19: iload_2 20: ifeq 34 23: aload_0 24: aload_1 25: aload_3 26: aload 4 28: invokespecial #25; //Method j$1:(Lscala/Function0;Lscala/runtime/IntRef; Lscala/runtime/VolatileByteRef;)I 31: goto 35 34: iconst_0 35: ireturn 看看IntRef和VolatileByteRef的创建?这些代替了通常只是私人vars来处理懒惰的val.现在j $1,为处理lazy val的检索和/或创建而创建的访问器方法,必须将这两个新创建的类作为参数(除了by-name函数). 因此,虽然底层的机制是相同的,但实现细节是不同的,效率低于你已经有另一个类来坚持变量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |