Scala 可变的 List。

7
几天前,我发现了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)

那里在发生什么?
1个回答

6
如果您查看List源代码,可以在这里看到cons ::类将其尾部定义为private[scala] var tl而不是val,因此它在内部是可变的。
这种变化发生在追加ListBuffer时,除非设置了exported标志。
toList方法中设置了这个标志,防止对相同的List进行进一步修改。
但是,toIterable是从SeqForwarder继承而来的->IterableForwarder,它不知道这样的事情,但是会返回与作为underlying值使用的相同的start对象,就像它所使用的一样

@Dima 我相信这是一个错误。 - Odomontois
似乎不仅仅是“追加”:例如,buf -= 3也会改变lst - Dima

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接