在下面的代码中,我测试了我对Scala懒惰评估的理解。
我尝试在函数定义中只处理一次集合。但是可以在下面看到processMap
被调用多个tiems。它应该只被调用一次吗?
val a = Array( ("1" , "1") , ("2" , "2")) //> a : Array[(String, String)] = Array((1,1), (2,2))
def toLazyMapDef(aparam : Array[(String, String)]) = {
lazy val toMap = processMap(aparam)
toMap
} //> toLazyMapDef: (aparam: Array[(String, String)])scala.collection.immutable.Ma
//| p[String,String]
def processMap(aparam : Array[(String, String)]) = {
println("in processMap")
aparam.toMap
} //> processMap: (aparam: Array[(String, String)])scala.collection.immutable.Map[
//| String,String]
println(toLazyMapDef(a)) //> in processMap
//| Map(1 -> 1, 2 -> 2)
println(toLazyMapDef(a)) //> in processMap
//| Map(1 -> 1, 2 -> 2)
println(toLazyMapDef(a)) //> in processMap
//| Map(1 -> 1, 2 -> 2)
答案 0 :(得分:4)
这里,lazy val toMap是函数的内部变量。它不会在函数调用之间保留。这可能是一个更好的例子(我们将lazy val作为类成员,我们可以证明它只被评估一次):
case class LazyMapDemo(aparam : Array[(String, String)]) {
lazy val toMap = processMap(aparam)
def giveLazyMap = toMap
def processMap(aparam : Array[(String, String)]) = {
println("in processMap")
aparam.toMap
}
}
scala> val a = Array( ("1" , "1") , ("2" , "2"))
a: Array[(String, String)] = Array((1,1), (2,2))
scala> val ld = LazyMapDemo(a)
ld: LazyMapDemo = LazyMapDemo([Lscala.Tuple2;@63f5faaa)
scala> ld.toMap
in processMap
res0: scala.collection.immutable.Map[String,String] = Map(1 -> 1, 2 -> 2)
scala> ld.toMap // processMap not called
res1: scala.collection.immutable.Map[String,String] = Map(1 -> 1, 2 -> 2)
scala> ld.giveLazyMap // processMap not called
res2: scala.collection.immutable.Map[String,String] = Map(1 -> 1, 2 -> 2)