I'm new with Scala so I'm starting with 开发者_开发知识库rewriting my old code in Scala. Now, I'm rewriting a Map, that contains some values and "history" of their modifications (like adding, deleting etc):
import scala.collection.immutable._
class Storage[A,+B](private var oldValues: Map[A,B]) extends Map[A,B] {
private var addedValues = new HashMap[A,B]
private var modifiedValues = new HashMap[A,B]
private var deletedValues = new HashSet[A]
}
When I overriding method "+" I can't compile it:
override def +[B1 >: B](kv: (A,B1)) = {
deletedValues = deletedValues - kv._1
addedValues = addedValues + kv //type mismatch; found : (A, B1) required: (A, B)
modifiedValues = modifiedValues + kv //type mismatch; found : (A, B1) required: (A, B)
currentValues()
}
Could someone tell me what can I do in this kind of situation?
The problem is the covariance of (the value type) B
. Since you're using mutable state, you should probably use the mutable Map
trait, which isn't covariant in type B
anyway. How about extending the HashMap
implementation? The following compiles, but I haven't tested it,
import collection.mutable._
class Storage[A,B](private var oldValues: Map[A,B]) extends HashMap[A,B] {
private var addedValues: Map[A,B] = new HashMap[A,B]
private var modifiedValues: Map[A, B] = new HashMap[A,B]
private var deletedValues: Set[A] = new HashSet[A]
// Overriding this method will redefine the behavior of HashMap.put and HashMap.+=
override def addEntry(e: DefaultEntry[A, B]) {
super.addEntry(e)
// your extension code below
val kv = (e.key, e.value)
deletedValues -= kv._1
addedValues += kv
modifiedValues += kv
// currentValues() // not defined yet
}
}
Calls like storage += (key, value)
will use your modified addEntry
method. If you haven't done so already, you might want to familiarize yourself with the source-code for HashMap
linked from the ScalaDoc.
You could make your class immutable.
import scala.collection.immutable._
class Storage[A,+B] private (
val oldValues: Map[A,B] = Map(),
val addedValues: Map[A, B] = Map(),
val modifiedValues: Map[A, B] = Map(),
val deletedValues: Set[A] = Set()) extends Map[A,B] {
override def +[B1 >: B](kv: (A,B1)) =
new Storage(oldValues,
addedValues + kv,
modifiedValues + kv,
deletedValues - kv._1)
...
}
精彩评论