我先举个例子,然后解释一下我看到的问题:
object Example extends App {
val arr = Array(0, 1, 2, 3, 4)
import scala.collection.mutable
val countMap = new mutable.LinkedHashMap[Int, Int] ++ arr.map(_ -> 1)
for {
(idx, count) <- countMap
// _ = idx + 1
} {
(idx + 1 to 4) foreach { i =>
countMap(i) += 3
}
println(s"$idx $count")
}
}
字符串
在上面的代码中,我创建了一个可变的HashMap
(使LinkedHashMap
按顺序打印),其中每个条目都被初始化为1
。并在一个循环中修改Hashmap中的一些条目,这些条目将在循环中稍后引用。println
语句打印它们更新的值。
但是如果我取消注解_ = idx + 1
行,我不会看到更新后的计数打印出来。相反,所有的计数都打印为1
的初始值。
我不明白为什么会有这种行为。
P.S.
1.Map的最终值将更新为相同的状态。
1.我在Scala 3中看到了同样的行为
object Blah extends App:
import scala.collection.mutable
val arr = Array(0, 1, 2, 3, 4)
val countMap = new mutable.LinkedHashMap[Int, Int] ++ arr.map(_ -> 1)
for
(idx, count) <- countMap.view
_ = idx + 1
do
(idx + 1 to 4) foreach { i =>
countMap(i) += 3
}
println(s"$idx $count")
型
1条答案
按热度按时间bgibtngc1#
for-comprehension是
foreach
,map
,flatMap
和filter
方法的语法糖。所以你必须用上面的术语来看待你的程序。因此,
for
后面的代码就变成了简单的foreach
字符串
现在,一旦你添加了一个
_ = idx + 1
,它确实会影响理解的转换方式。型
现在,在最后调用
foreach
之前添加了一个map
方法。map
方法将整个countMap
转换为一个新集合,每个元素都复制到一个新集合中。一旦创建了这个集合,就会调用foreach
方法的主体。您可以通过在
countMap.view
上写入for
来“解决”这个问题,这可以防止创建新的集合。型
最后一点,scala默认支持不变性。即使有可变的集合,也必须小心使用。此外,在遍历集合时不应该改变它们。这会带来程序不希望的和隐藏的(错误)行为。