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