scala 可变值列表

scala mutable val List

几天前,我发现了 Paul Philip 的要点 https://gist.github.com/paulp/9085746,其中显示了非常奇怪的行为。 我没有找到任何解释怎么可能

简化的代码片段:

val buf = new ListBuffer[Int]()
buf ++= Seq(1,2,3)
val lst: List[Int] = buf.toIterable.toList
println(lst) //List(1,2,3)
buf ++= Seq(4,5,6)
println(lst) //List(1,2,3,4,5,6)

它在没有 toIterable

的情况下按预期工作
val buf = new ListBuffer[Int]()
buf ++= Seq(1,2,3)
val lst: List[Int] = buf.toList
println(lst) //List(1,2,3)
buf ++= Seq(4,5,6)
println(lst) //List(1,2,3)

那里发生了什么事?

如果您查看 List source,您会发现 cons :: class 的尾部定义为 private[scala] var tl 而不是 val , 所以它在内部是可变的。

除非设置 exported 标志,否则此突变正在发生 during ListBuffer append

此标志在 the toList method 中设置,防止进一步修改相同 List

但是 toIterable 继承自 SeqForwarder -> IterableForwarder,它不知道这样的事情,但是返回相同的 start 对象 as it used as underlying value