2013-08-21 55 views
0

在斯卡拉懒惰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运算符(方法)初始化所有三个变量?

+0

检查http://stackoverflow.com/questions/7484928/what-does-a-lazy-val-do – Ankur

回答

1

懒惰val在第一次访问它们时被初始化,它在访问之后被计算,然后从api的角度变成一个简单的val(有关实现的some笔记,以及this SIP的其他信息)。

所以是的,如果你的patMat结构是你访问val的第一个地方,那么它将构成一个包含vals值的三个元素的元组。

match不是方法或运算符它是一个语言级别的构造。

0

Scala specification

懒惰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; 
       } 
      } 
     } 
    } 
5

您可以在这里删除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没有评估,aStream创建评估,并在b方法#::.unapply评估。