Scala逆向困难

时间:2011-08-27 23:22:15

标签: scala contravariance

我是Scala的新手,所以我开始在Scala中重写旧代码。现在,我正在重写一个Map,它包含一些值和修改的“历史”(如添加,删除等):

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]  
}

当我重写方法“+”时,我无法编译它:

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()
}

有人可以告诉我在这种情况下我该怎么办?

2 个答案:

答案 0 :(得分:3)

问题是(值类型)B的协方差。由于您使用的是可变状态,因此您应该使用可变Map特征,无论如何,它都不是B类型中的协变。如何扩展HashMap实施?以下编译,但我没有测试过,

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
  }
}

storage += (key, value)之类的通话将使用您修改后的addEntry方法。如果您还没有这样做,可能需要熟悉the ScalaDoc链接的HashMap源代码。

答案 1 :(得分:3)

你可以让你的课程不可变。

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)
  ...
}