lazy val是什么作用?
lazy val是什么作用?
我注意到Scala提供lazy vals
。但我不知道它们的作用。
scala> val x = 15 x: Int = 15 scala> lazy val y = 13 y: Int = scala> x res0: Int = 15 scala> y res1: Int = 13
REPL显示y
是一个lazy val
, 但它和普通的val
有什么不同呢?
admin 更改状态以发布 2023年5月21日
这个功能不仅有助于延迟昂贵的计算,而且还有助于构建相互依赖或循环结构。例如,这会导致堆栈溢出:
trait Foo { val foo: Foo } case class Fee extends Foo { val foo = Faa() } case class Faa extends Foo { val foo = Fee() } println(Fee().foo) //StackOverflowException
但使用惰性值就可以正常工作了
trait Foo { val foo: Foo } case class Fee extends Foo { lazy val foo = Faa() } case class Faa extends Foo { lazy val foo = Fee() } println(Fee().foo) //Faa()
它们之间的区别在于,val
在定义时执行,而lazy val
在第一次访问时执行。\n
scala> val x = { println("x"); 15 } x x: Int = 15 scala> lazy val y = { println("y"); 13 } y: Int =scala> x res2: Int = 15 scala> y y res3: Int = 13 scala> y res4: Int = 13
\n与使用def
定义的方法不同,lazy val
只执行一次,以后不再执行。当操作需要很长时间才能完成,且不确定是否会稍后使用时,这非常有用。\n
scala> class X { val x = { Thread.sleep(2000); 15 } } defined class X scala> class Y { lazy val y = { Thread.sleep(2000); 13 } } defined class Y scala> new X res5: X = X@262505b7 // we have to wait two seconds to the result scala> new Y res6: Y = Y@1555bd22 // this appears immediately
\n在这里,如果值x
和y
从未被使用,则只有x
浪费了资源。如果我们假设y
没有副作用,并且我们不知道它被访问的频率(从未、一次、成千上万次),则将其声明为def
是无用的,因为我们不想多次执行它。\n如果您想了解lazy val
的实现方式,请参见这个问题。