什么时候lazy val被初始化了?

MyT*_*tle 0 scala lazy-evaluation

什么时候在Scala lazy val初始化?换句话说,以下代码将变量声明为惰性有一些好处吗?

  lazy val xOption = table.get(x)
  lazy val yOption = table.get(y)
  lazy val xyOption = table.get(x + y)

 (xOption, yOption, xyOption) match { ... }
Run Code Online (Sandbox Code Playgroud)

matchoperator(方法)是否初始化所有三个变量?

sen*_*nia 5

你可以match在这里删除:

(xOption, yOption, xyOption)
Run Code Online (Sandbox Code Playgroud)

这个表达式创建Tuple3.没有语法糖:

Tuple3.apply(xOption, yOption, xyOption)
Run Code Online (Sandbox Code Playgroud)

apply 方法声明:

def apply[T1, T2, T3](_1: T1, _2: T2, _3: T3): (T1, T2, T3)
Run Code Online (Sandbox Code Playgroud)

所有参数都是call-by-value,因此在apply方法评估之前评估参数值.

随着call-by-name参数lazy val将不进行评估.

match调用unapply方法,因此评估取决于unapply方法实现:

lazy val a = { println("a"); 1 }
lazy val b = { println("b"); 1 }
lazy val c = { println("c"); 1 }

scala> val s = a #:: b #:: c #:: Stream.empty
a
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> s match {
     |   case x #:: _ => x
     | }
b
res0: Int = 1
Run Code Online (Sandbox Code Playgroud)

如您所见c,未评估,a将在Stream创建时进行评估,并b#::.unapply方法中进行评估.