Scala是否懒惰?
当我打电话时Scala是否懒惰?,scala,dictionary,mapping,lazy-evaluation,Scala,Dictionary,Mapping,Lazy Evaluation,当我打电话时 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中有一个调试打印语句
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”之后会调用debug print语句,也不明白为什么会得到它两次——除非mapValues
创建了一个惰性映射?。它映射到一个中间类,该类包含fn
,在访问之前(一次又一次)不会求值
如果不希望延迟计算,请使用严格的map
。即:
collection map { case (k, v) => (k, fn(v)) }
请记住,
MappedValues
实现在每次访问时都对函数求值,这与Scalalazy val
只求值一次不同。
在单步执行代码时,可能会看到两次输出。在调试器窗口中展开val foo
,将迭代这些值,调用函数fn
,并生成调试输出
如果您为map
t
和functionfn
提供代码,那么我们可能会提供帮助。关键功能是,您不需要在mapValues
之后重新刷新map,因为键没有更改。对于您的示例中的map
,编译器无法提供保证。这很好——主要是(一如既往)意外行为令人不安,需要跟踪,而不是导致具体问题。但是谢谢你的帮助。
collection map { case (k, v) => (k, fn(v)) }