Scala mapValues 是懒惰的吗?

Is Scala mapValues lazy?

当我打电话时

System.err.println("Before")
System.err.flush()
val foo: Map[Int, T] = t mapValues (fn(_))
System.err.println(foo.head) //prevent optimiser from delaying the construction of 'foo' 
System.err.println("After")
System.err.flush()

fn 里面有一个调试打印语句,我得到这个输出:

Before
...head item...
After
...debug print statement from fn...
...debug print statement from fn...

我不明白为什么在打印 "After" 之后调用调试打印语句,而且我不明白为什么我得到它两次 --- 除非 mapValues 创建一张懒惰的地图?

Yes it is。它映射到一个包含 fn 的中间 class 并且直到访问(一次又一次)才进行评估。

def mapValues[W](f: V => W): Map[K, W] = new MappedValues(f)

如果您不想延迟计算,请使用严格的 map。即:

collection map { case (k, v) => (k, fn(v)) }

请记住,MappedValues 实现会在每次访问时对函数求值——不同于仅求值一次的 Scala lazy val。 单步执行代码时,您可能会看到两次输出。在调试器 window 中扩展 val foo 将迭代这些值,调用函数 fn 并生成调试输出。

如果您提供映射 t 和函数 fn 的代码,那么我们或许可以提供帮助。