Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala类型的问题:SoftReference、ReferenceQueues、SoftHashMap_Scala_Types_Reference - Fatal编程技术网

scala类型的问题:SoftReference、ReferenceQueues、SoftHashMap

scala类型的问题:SoftReference、ReferenceQueues、SoftHashMap,scala,types,reference,Scala,Types,Reference,编辑到目前为止,大多数答案都集中在我错误地扩展地图这一事实上。我已经在示例代码中纠正了这一点,但类型问题仍然存在,问题仍然存在 我试图在Scala中实现SoftHashMap,但遇到类型不匹配错误: inferred type arguments [K,V] do not conform to class SoftValue's type parameter bounds [K,+V <: AnyRef] val sv = new SoftValue(kv._1, kv._2, queue

编辑到目前为止,大多数答案都集中在我错误地扩展地图这一事实上。我已经在示例代码中纠正了这一点,但类型问题仍然存在,问题仍然存在

我试图在Scala中实现
SoftHashMap
,但遇到类型不匹配错误:

inferred type arguments [K,V] do not conform to class SoftValue's type parameter bounds [K,+V <: AnyRef]
val sv = new SoftValue(kv._1, kv._2, queue)

推断的类型参数[K,V]不符合类SoftValue的类型参数界限[K,+V正如Sam指出的,第一个问题是您正在扩展
scala.collection.immutable.Map
,您正在通过别名
scala.Map
访问它

第二,您已将
V
声明为协变类型参数。这意味着
SoftMap[String,Dog]
SoftMap[String,Any]
的子类型。在类定义中以逆变位置引用协变类型参数是无效的

trait Contra[+A] {
    def a: A    // method return type is a covariant position, okay
    def m(a: A) // method parameter is a contravariant position, error
    def n[AA >: A](a: AA) // upper bound of a type param is in covariant position, okay
}
Typesafe可变集合需要在协变和逆变位置引用元素类型:分别检索元素和添加元素。因此,它们必须将类型参数声明为不变量

collection.mutable.Map
的定义显示:

trait Map[A, B] 
  extends Iterable[(A, B)]
     with scala.collection.Map[A, B] 
     with MapLike[A, B, Map[A, B]]
如果您延长此期限,您将被告知:

scala> trait SoftMap[K, +V] extends collection.mutable.Map[K, V]
<console>:25: error: covariant type V occurs in invariant position in type [K,+V]java.lang.Object with scala.collection.mutable.Map[K,V] of trait SoftMap
       trait SoftMap[K, +V] extends collection.mutable.Map[K, V]
             ^

Sam还指出的最后一个问题是,至少从Scala 2.8开始,
+
方法就没有了。你应该实现。

如果
软地图
是可变的,那么你就不能用它的值类型
V
的超类型更新它。如果可能的话,旧地图将绑定到key值对的值类型为
V1
,旧映射的类型为
V
。这将导致在旧映射中查找新绑定时出现类型错误

可变映射通过复制映射实现
+
,不可变映射具有更高效的
+
。另一方面,可变映射具有
+=
,可以修改现有映射,并且效率更高。
+=
的参数是键和值,其中值不是映射值类型的超类型

在这种情况下,解决方案是复制地图

编辑:

更改上述问题后得到的错误消息是因为软映射的类型参数
V
可以是任何类型,而
SoftValue
的类型
V
必须是
AnyRef
的子类型(不能是
Int
Float
,即
AnyVal
的子类型)因此,您不能从
软地图
中创建类型为
V
SoftValue
,因为有人可能会通过将
V
设置为
Int
来实例化
SoftMap
,比如说
Int

,这是编译的。(编辑:我最初添加了
val value
,但这创建了一个强引用).不确定要如何处理迭代器

import scala.collection.mutable.{Map, HashMap}    
import scala.ref._

class SoftValue[K, +V <: AnyRef](val key:K, value:V, 
  queue:ReferenceQueue[V]) extends SoftReference(value, queue)

class SoftMap[K, V <: AnyRef] extends Map[K, V] {
  private val map = new HashMap[K, SoftValue[K, V]]
  private val queue = new ReferenceQueue[V]

  def +=(kv: (K, V)): this.type = {
    val sv = new SoftValue(kv._1, kv._2, queue)
    map(kv._1) = sv
    this
  }

  def -=(k: K): this.type = { map -= k; this }
  def get(k: K) = map.get(k).flatMap(_.get)
  def iterator: Iterator[(K,V)] = error("todo")
}
import scala.collection.mutable.{Map,HashMap}
导入scala.ref_

类SoftValue[K,+V第一件事。是否扩展scala.collection.mutable.Map?在任何情况下,Map中的“+”返回Map的一个新实例(“创建一个包含新的键/值映射和此映射的所有键/值映射的新映射”)。要查看完整的实现,请签出:
scala> trait SoftMap[K, V] extends collection.mutable.Map[K, V]
defined trait SoftMap
import scala.collection.mutable.{Map, HashMap}    
import scala.ref._

class SoftValue[K, +V <: AnyRef](val key:K, value:V, 
  queue:ReferenceQueue[V]) extends SoftReference(value, queue)

class SoftMap[K, V <: AnyRef] extends Map[K, V] {
  private val map = new HashMap[K, SoftValue[K, V]]
  private val queue = new ReferenceQueue[V]

  def +=(kv: (K, V)): this.type = {
    val sv = new SoftValue(kv._1, kv._2, queue)
    map(kv._1) = sv
    this
  }

  def -=(k: K): this.type = { map -= k; this }
  def get(k: K) = map.get(k).flatMap(_.get)
  def iterator: Iterator[(K,V)] = error("todo")
}