在斯卡拉懒惰val初始化?换句话说,下面的代码将变量声明为懒惰会带来一些好处吗?当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 { ... }
是否match
运算符(方法)初始化所有三个变量?
在斯卡拉懒惰val初始化?换句话说,下面的代码将变量声明为懒惰会带来一些好处吗?当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 { ... }
是否match
运算符(方法)初始化所有三个变量?
懒惰MODI网络呃适用于值的DE网络nitions。
第一次访问懒惰值时(根本不会发生 )。尝试在其初始化期间访问惰性值可能会导致循环行为。如果在初始化期间抛出异常 ,则该值被认为是未初始化的, ,稍后访问将重试以评估其右侧。
简而言之,它会在您第一次使用它时初始化。在你的情况下,第一次调用表达式match
。尽管到那时表格需要有x
。
如果你看到它的实现(从Scala 2.10开始,在未来的版本中会改变):它使用着名的双锁定成语: 私有volatile结果;
public T getValue() {
if (result != null) {
return result;
} else {
synchronized (this) {
if (result == null) {
result = //initialize
return result;
} else {
return result;
}
}
}
}
您可以在这里删除match
:
(xOption, yOption, xyOption)
这个表达式创建Tuple3
。如果没有语法糖:
Tuple3.apply(xOption, yOption, xyOption)
apply
方法声明:
def apply[T1, T2, T3](_1: T1, _2: T2, _3: T3): (T1, T2, T3)
所有参数都call-by-value
,所以参数值之前apply
评价方法评价。
随着call-by-name
参数lazy val
将不会被评估。
match
调用unapply
方法,使评价取决于unapply
方法implementstion:
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
正如你可以看到c
没有评估,a
上Stream
创建评估,并在b
方法#::.unapply
评估。
检查http://stackoverflow.com/questions/7484928/what-does-a-lazy-val-do – Ankur