val eventListeners = new HashMap[Class[Event], ArrayBuffer[Event => Unit]]
def addEventListener[A <: Event](f: A => Unit)(implicit mf: ClassManifest[A]): A => Unit = {
eventListeners.getOrElseUpdate(mf.erasure.asInstanceOf[Class[Event]], ArrayBuffer[Event => Unit]()) += f
f
}
投掷:
error: type mismatch;
found : (A) => Unit
required: (this.Event) => Unit
eventListeners.getOrElseUpdate(mf.erasure.asInstanceOf[Class[Event]], ArrayBuffer[Event => Unit]()) += f
为什么说它找到(A) => Unit
? f
的值是(Event) => Unit
的函数。 A
只是一个类型参数,而不是签名吗?
示例电话:
addEventListener { e:FooEvent => .... }
答案 0 :(得分:7)
班级Function1
对其参数具有反变量。即,它的类型是Function1[-T, +R]
。
这意味着Any => Unit
的函数是Event => Unit
的子类型,但A
的子类型为Event
,A => Unit
是Event => Unit
的_super_type 1}}。
问题,问题。如果您将类型参数更改为A >: Event
,它应该可以正常工作。
答案 1 :(得分:4)
您承诺,ArrayBuffer
您将为其提供一个可以接受任何Event
并将其转换为Unit
的功能(可能会在此过程中做一些有趣的事情)。
但是你给它一个只能A
s的函数,它可能不包含所有Event
s。这显然不是你所承诺的,所以编译器会抱怨。
你需要弄清楚在这种情况下应该发生什么,并相应地编写代码。例如,您可以创建一个新函数g
,如果它收到Event
,根据您的班级清单,它不是A
,并且以其他方式应用{{1} }}。或者你可以要求所有听众都参加各种各样的活动,并自己负责抛弃他们不想打扰的事件。
编辑:只是为了让事情更加清晰,
f