【问题标题】:Is Scala mapValues lazy?Scala mapValues 是懒惰的吗?
【发布时间】:2017-01-21 07:23:29
【问题描述】:

当我打电话时

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 创建一个惰性映射?

【问题讨论】:

    标签: scala dictionary mapping lazy-evaluation


    【解决方案1】:

    Yes it is。它映射到一个包含fn 的中间类,直到访问(一次又一次)才评估。

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

    如果您不想延迟评估,请使用严格的map。那就是:

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

    【讨论】:

    • 关键特性是你不需要在mapValues 之后重新哈希映射,因为键没有改变。以您的map 为例,编译器无法提供保证。
    【解决方案2】:

    请记住,MappedValues 实现会在每次访问时评估函数——这与只评估一次的 Scala lazy val 不同。 单步执行代码时,您可能会看到两次输出。在调试器窗口中展开val foo 将遍历这些值,调用函数fn 并生成调试输出。

    如果您提供地图t 和函数fn 的代码,我们或许可以提供帮助。

    【讨论】:

    • 没关系 - 主要是(一如既往)意外行为令人不安,需要追踪,而不是导致具体问题。但感谢您提供帮助。
    猜你喜欢
    • 2018-01-28
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多