lazy val是什么作用?

13 浏览
0 Comments

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日
0
0 Comments

这个功能不仅有助于延迟昂贵的计算,而且还有助于构建相互依赖或循环结构。例如,这会导致堆栈溢出:

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()

0
0 Comments

它们之间的区别在于,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在这里,如果值xy从未被使用,则只有x浪费了资源。如果我们假设y没有副作用,并且我们不知道它被访问的频率(从未、一次、成千上万次),则将其声明为def是无用的,因为我们不想多次执行它。\n如果您想了解lazy val的实现方式,请参见这个问题

0