【问题标题】:Scala contravariance difficultiesScala逆变困难
【发布时间】:2011-08-27 23:22:15
【问题描述】:

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

谁能告诉我在这种情况下我该怎么办?

【问题讨论】:

    标签: scala contravariance


    【解决方案1】:

    问题是(值类型)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 的源代码。

    【讨论】:

      【解决方案2】:

      你可以让你的类不可变。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-27
        • 2016-07-27
        • 2013-04-10
        • 1970-01-01
        • 2015-02-09
        • 2013-12-27
        • 1970-01-01
        相关资源
        最近更新 更多