在之前的SO post中,我问到了一种惯用的方法来使一个容器类包装一个线程安全的不可变集合。我收到的所有涉及使用各种风格的读/写锁或同步的答案不是我想要的。如何让一个类包装一个不可变的集合在Scala中不可变?
让我问一个不同的问题。我如何让以下类包装一个不可变的容器?该方法add
/remove
需要返回一个新MyContainer
类实例适当改变,但我不能完全看怎么办呢?
class MyContainer[A] {
// method that returns a new MyContainer that includes the additional thing...
def add(thing: A): MyContainer[A] = {
???
}
def filter(p: A => Boolean): Option[Iterable[A]] = {
val filteredThings = backingStore.values.filter(p)
if (filteredThings.isEmpty) None else Some(filteredThings)
}
// method that returns a new MyContainer that does not include the thing with given uuid
def remove(uuid: UUID): MyContainer[A] = {
???
}
@ volatile private[this] var backingStore = immutable.HashMap.empty[UUID, A]
}
的思考?
编辑:回应置评,一个可能的解决办法是遵循类似的东西...
class MyContainer[A](val backingStore: immutable.HashMap[UUID, A]) {
def add(thing: A): MyContainer[A] = {
new MyContainer(backingStore + (thing.uuid -> thing))
}
def filter(p: A => Boolean): Option[Iterable[A]] = {
val filteredThings = backingStore.values.filter(p)
if (filteredThings.isEmpty) None else Some(filteredThings)
}
def remove(uuid: UUID): MyContainer[A] = {
new MyContainer(backingStore - uuid)
}
}
... backingStore
不再是私有的(但可以把private
在构造函数)。更多的想法?
以'backingStore'开始''val'而不是'@volatile var',并且看到哪里会导致......(编辑:错字) –
为了使'backingStore'本身是私人的(但不是构造函数),你可以删除'val'(或者显式地写'private val')。 –