我尝试了我的计划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())
为什么呢?欢迎任何提示。感谢
答案 0 :(得分:2)
API documentation for Map.filterKeys说:
@returns一个不可变的映射,只包含该映射的那些键值对,其中键满足谓词p。生成的地图包装原始地图而不复制任何元素。
这意味着filterKeys
不会急切地开始评估,而是构建一个隐藏某些键的惰性视图。在您实际尝试访问密钥之前,不会对谓词进行评估,在这种情况下,直到您遍历地图为止。
迭代由toString
方法触发。
一旦编写toString
,REPL(在本例中为Scastie)就会调用r
上的r
方法,因为它必须生成结果的字符串表示。 / p>
请注意,如果您运行与脚本相同的程序,则不会打印任何内容:作为脚本运行时,不会在中间结果上调用toString
,因此无需遍历地图,因此无需1}}未被调用。