scala - 如何在需要时完全忽略对象的类型参数

scala - How to completely ignore an object's type parameter when needed

给定以下 Scala 2.11 代码:

class Partials {
  class Aggregate
  class AggregateId[T <: Aggregate]
  class Event[T <: Aggregate]

  type EventListener = PartialFunction[Event[_], Unit]

  val listeners = mutable.Set[EventListener]()

  def addListener(l: EventListener) {
    listeners += l
  }

  def process(e: Event[_]): Unit = {
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e))
  }

  addListener {
    case x => println(x)
  }
}

这是根据我的实际代码(一些事件处理)进行了简化,但它显示了相同的问题。我有引用某些聚合的事件,并且我有应该能够处理这些事件的侦听器。侦听器是 PartialFunctions,因此它们可以处理一些事件子类型,但不是全部。

如所列,我在最后的 addListener 调用中收到以下错误:

type arguments [_] do not conform to class Event's type parameter bounds [T <: Partials.this.Aggregate]
  addListener {

当我将 EventListener 类型别名更改为

type EventListener = PartialFunction[Event[_ <: Aggregate], Unit]

我在 process 方法中得到以下错误:

Error:(19, 60) type mismatch;
 found   : Partials.this.Event[_] where type _
 required: Partials.this.Event[_ <: Partials.this.Aggregate]
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e))

Error:(19, 79) type mismatch;
 found   : Partials.this.Event[_] where type _
 required: Partials.this.Event[_ <: Partials.this.Aggregate]
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e))

目前我真的不明白发生了什么。 Event 需要它的类型参数来处理与此无关的事情,但是对于应该处理事件的 PartialFunctions,我想简单地忽略该类型参数,这就是我认为我对 [_].我哪里错了?

这似乎有效:

import scala.collection.mutable

class Partials {
  class Aggregate
  class AggregateId[T <: Aggregate]
  class Event[T <: Aggregate]

  type EventListener = PartialFunction[Event[_ <: Aggregate], Unit]

  val listeners = mutable.Set[EventListener]()

  def addListener(l: EventListener) {
    listeners += l
  }

  def process(e: Event[_ <: Aggregate]) {
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e))
  }

  addListener {
    case x => println(x)
  }
}

注意 process 方法是如何定义的。这些错误消息告诉您,当您将 listener 的类型定义为 PartialFunction[Event[_ <: Aggregate], Unit] 时,您需要将 Event[_ <: Aggregate] 的实例传递给 listenerisDefinedAtapply 方法。