scala类型的问题:SoftReference、ReferenceQueues、SoftHashMap
编辑到目前为止,大多数答案都集中在我错误地扩展地图这一事实上。我已经在示例代码中纠正了这一点,但类型问题仍然存在,问题仍然存在 我试图在Scala中实现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
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")
}