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

why variable computed after called in Scala

我尝试了我的程序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())

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

API documentation for Map.filterKeys 说:

@returns an immutable map consisting only of those key value pairs of this map where the key satisfies the predicate p. The resulting map wraps the original map without copying any elements.

这意味着filterKeys不会急切地开始评估,而是构造一个隐藏一些键的惰性视图。在您实际尝试访问键之前,或者在这种情况下,直到您遍历映射,才会评估谓词。

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

请注意,如果您 运行 将同一程序作为脚本,则不会打印任何内容:当 运行 作为脚本时,不会对中间结果调用 toString,因此没有需要遍历地图,因此 toString 不会被调用。