可变 Scala 集合的不可修改视图 [英] Unmodifiable view of a mutable Scala collection

查看:56
本文介绍了可变 Scala 集合的不可修改视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有私有字段的类,它是一个可变集合.这个特定实例中的字段是 ArrayBuffer,尽管我的问题扩展到任何有限的、有序的、随机访问的集合类型.我想公开这个字段,不允许其他人修改它.在 Java 中,我会添加一个方法,如:

I have a class with a private field that is a mutable collection. The field in this particular instance is an ArrayBuffer, although my question extends to any finite, ordered, random-access collection type. I want to expose this field without permitting others to modify it. In Java I would add a method like:

private List<T> theList;

public List<T> getList() {
    return Collections.unmodifiableList(theList);
}

在 Java 中,我们只接受结果是一个 List,它没有完全实现 List 接口,因为 #add 和朋友抛出UnsupportedOperationException.

In Java we just accept that the result is a List that doesn't fully implement the List interface because #add and friends throw UnsupportedOperationException.

在 Scala 中,我希望找到一个合适的 trait 和访问器,如 iteratorsizeapply(用于通过索引检索值) 但没有突变体.是否存在我还没有发现的这种类型?

In Scala, I would expect to find an appropriate trait with accessors like iterator, size, and apply (for retrieving values by index) but no mutators. Does such a type exist that I just haven't found yet?

推荐答案

Scala 集合库是面向不变性的,不变性不仅仅指的是不允许修改给定的集合,还包括您保证该集合不会被任何人修改.

The Scala collection library is oriented to immutability, and immutability doesn't refer only to the fact that you are not allowed to modify a given collection, but also that you are guaranteed that the collection won't be ever modified by anyone.

因此,您不能也不应该从 Scala 中的可变缓冲区中获取像 immutable.Seq 这样的集合作为视图,因为它违反了这一保证.

So you cannot and you shouldn't get a collection like immutable.Seq as a view from a mutable buffer in Scala since it breaks that guarantee.

但是您可以很容易地实现不可修改的可变 Seq 的概念,如下所示:

But you can implement the concept of unmodifiable mutable Seq easy enough like so:

class UnmodifiableSeq[A](buffer: mutable.Seq[A]) extends mutable.Seq[A]{
    def update(idx: Int, elem: A) {throw new UnsupportedOperationException()}

    def length = buffer.length

    def apply(idx: Int) = buffer(idx)

    def iterator = buffer.iterator
}

用法:

val xs = Array(1, 2, 3, 4)
val view = new UnmodifiableSeq(xs)
println(view(2)) >> 3
view(2) = 10 >> Exception in thread "main" java.lang.UnsupportedOperationException

获得不可修改的集合视图的一种可能更好的方法是向下转换到 collection.Seq,它不提供可变更新操作:

A probably better way of obtaining an unmodifiable view of the collection is by downcasting to collection.Seq which provides no mutable update operations:

val xs = Array(1, 2, 3)
val view: Seq[Int] = xs //this is unmodifiable

或者创建一个扩展 Seq 的包装器,如果您有自己的自定义可变类.

or creating a wrapper which extends Seq if you have your own custom mutable class.

class UnmodifiableView[A](col: MutableCollection[A]) extends collection.Seq[A]{
    def length = col.length

    def apply(idx: Int) = col(idx)

    def iterator = col.iterator
}

scala.collection.Seq trait 不保证任何不变性,但它也不允许任何修改操作,因此它看起来非常合适.

The scala.collection.Seq trait does not make any guarantees of immutability but it also does not allow any modifying operations so it seems the perfect fit.

这篇关于可变 Scala 集合的不可修改视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆