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
的代码,那么我们或许可以提供帮助。
当我打电话时
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
的代码,那么我们或许可以提供帮助。