Map.contains具有超类型的键类型

时间:2015-08-19 14:33:57

标签: scala collections

我有一个案例

result = sorted(result.items(), key=lambda k: k[1][0][1]["ranking"], reverse=True)

由于地图的密钥类型不变,这不起作用:

trait EventLike
trait Event extends EventLike

trait API {
  private var map = Map.empty[Event, Any]

  def contains(e: EventLike): Boolean = map.contains(e)
}

什么是良好的解决方案,最低性能损失。也就是说,我特别不想介绍这个可怕的事情:

<console>:58: error: type mismatch;
 found   : EventLike
 required: Event
             def contains(e: EventLike): Boolean = map.contains(e)
                                                                ^

我可以使用不同的 def contains(e: EventLike): Boolean = e match { case e1: Event => map.contains(e1) case _ => false } 实现(可能是可变的,因为这是本地的线程)吗?

2 个答案:

答案 0 :(得分:2)

您可以将地图声明为Map[EventLike, Any]

trait API {
  private var map = Map.empty[EventLike, Any]
  def contains(e: EventLike): Boolean = map.contains(e)

  def add(e:Event): Unit = {
    map += (e -> ???)
  }
}

您仍然可以使用Event键填充地图,同时搜索EventEventLike

<强> UPD

如果您不介意使用Java可变集合,则可以使用HashMap,它接受​​任何对象作为包含的参数,而不管地图的类型参数如何:

trait API {
  private val map = new java.util.HashMap[Event, Any]
  def contains(e: EventLike): Boolean = map.containsKey(e)
}

答案 1 :(得分:0)

EventLikeEvent的超类型,因此即使Map的密钥类型是协变的,这也不会起作用。

您基本上想要检查EventLike是否为Event,并且您只能在运行时使用您的解决方案或类似

这样做
def contains(e: EventLike): Boolean =
  e.isInstanceOf[Event] && map.contains(e.asInstanceOf[Event]

在您的情况下,静态类型检查不会起作用吗?

def contains(e: Event): Boolean = map.contains(e)