Scala:索引序列的可变性以及转换为mutable和back时会发生什么

时间:2013-10-19 17:22:24

标签: scala immutability toarray mutability

我最近多次遇到过这种情况:

  1. 一个类有一个不可变(索引?)序列成员
  2. 工厂成员方法创建一个序列有些修改的新实例
  3. 这是一种有效的方法吗?

    class A( xs: IndexedSeq[Int] ) {
        def another: A = {
            val ys = xs.toArray.clone()   // !!!
            ys(7) = 13
            new A(ys)
        }
    }
    

    我做.toArray以便我可以修改这个序列和.clone,因为我担心如果原来的xs已经是一个数组,toArray将只返回这个并且我将修改对象(意味着 - 不可变的)价值观。但是,如果xs不是数组,这显然会产生两个副本,我真的想避免这种情况。显然,我可以检查它的类型,但这似乎非常不优雅,我不太确定我是否必须检查其他可以包装数组的可变序列。怎么办?

    scala> val xs: Seq[Int] = Array(1, 2, 3)
    ss: Seq[Int] = WrappedArray(1, 2, 3)
    
    scala> val ys = xs.toArray
    ys: Array[Int] = Array(1, 2, 3)
    
    scala> ys(1) = 22
    
    scala> ys
    res1: Array[Int] = Array(1, 22, 3)
    
    scala> xs
    res2: Seq[Int] = WrappedArray(1, 22, 3)
    

1 个答案:

答案 0 :(得分:2)

如果你真的不需要可变性,那么最好只是要求一个不可变的序列;这样你就不必担心改变数据是否有副作用。

class A(xs: collection.immutable.IndexedSeq[Int]) {
  def another: A = {
    val ys = xs.updated(7, 13)
    new A(ys)
  }
}