为什么在Scala中调用后计算变量

时间:2018-05-15 00:51:45

标签: scala scala-collections

我尝试了我的计划https://scastie.scala-lang.org/RhCRxZkEQUqbC2gpiRtKnA

我的节目:

val m = Map((1, "abc"), (2, "aaa"), (4, "aaaaaa"), (3, "a"), (5, "78"))
var mm :Map[Int, String] = Map.empty

val r = m.filterKeys { k =>
  if(k>3) true else {
    println(k)
    mm += (k -> m(k))
    false
  }
}

println("end of program", mm)

r // last line

输出

(end of program,Map())
1
2
3

如果删除了最后一行r,则输出为

(end of program,Map())

为什么呢?欢迎任何提示。感谢

1 个答案:

答案 0 :(得分:2)

API documentation for Map.filterKeys说:

  

@returns一个不可变的映射,只包含该映射的那些键值对,其中键满足谓词p。生成的地图包装原始地图而不复制任何元素。

这意味着filterKeys不会急切地开始评估,而是构建一个隐藏某些键的惰性视图。在您实际尝试访问密钥之前,不会对谓词进行评估,在这种情况下,直到您遍历地图为止。

迭代由toString方法触发。 一旦编写toString,REPL(在本例中为Scastie)就会调用r上的r方法,因为它必须生成结果的字符串表示。 / p>

请注意,如果您运行与脚本相同的程序,则不会打印任何内容:作为脚本运行时,不会在中间结果上调用toString,因此无需遍历地图,因此无需