这怎么会是类型不匹配呢?
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) =>单位?
f
的值是一个函数,即 (Event) =>单位
。 A
不只是一个类型参数,而不是签名吗?
调用示例: addEventListener { e:FooEvent =>; .... }
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
}
Is throwing:
error: type mismatch;
found : (A) => Unit
required: (this.Event) => Unit
eventListeners.getOrElseUpdate(mf.erasure.asInstanceOf[Class[Event]], ArrayBuffer[Event => Unit]()) += f
Why is it saying that it found (A) => Unit
? The value of f
is a function that is (Event) => Unit
. Isn't A
just a type parameter, not the signature?
Example call:addEventListener { e:FooEvent => .... }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Function1
类的参数是逆变的。即,其类型为Function1[-T, +R]
。这意味着
Any => 的函数Unit
是Event => 的子类型Unit
,但对于A
是Event
的子类型,A => Unit
是Event => 的 _super_type单位
。因此,问题来了。如果将类型参数更改为
A >: Event
,它应该可以工作。The class
Function1
is contra-variant on its parameter. Ie, its type isFunction1[-T, +R]
.That means a function of
Any => Unit
is a subtype ofEvent => Unit
, but forA
a subtype ofEvent
,A => Unit
is a _super_type ofEvent => Unit
.Ergo, the problem. If you change the type parameter to
A >: Event
, it should work.您向
ArrayBuffer
承诺,您将为它提供一个可以接受任何Event
并将其转换为Unit
的函数(大概是在做一些有趣的事情)道路)。但是您给它的函数只能接受
A
,它可能不包含所有Event
。这显然不是你所承诺的,所以编译器会抱怨。您需要弄清楚在这种情况下应该发生什么,并相应地编写代码。例如,您可以创建一个新函数
g
,如果它收到一个Event
(根据您的类清单)不是A
,则不执行任何操作code>,否则应用f
。或者,您可以要求所有侦听器接收各种类型的事件,并自行负责丢弃他们不想理会的事件。编辑:只是为了通过一个例子让事情变得更清楚,
You are promising your
ArrayBuffer
that you will give it a function that can take anyEvent
and turn it into aUnit
(presumably doing something interesting along the way).But you are giving it a function that can only take
A
s, which may not encompass allEvent
s. That is clearly not what you've promised, so the compiler complains.You need to figure out what ought to happen in that case, and write code accordingly. For example, you could create a new function
g
that does nothing in case it receives anEvent
that, according to your class manifest, is not anA
, and otherwise appliesf
. Or you could require all listeners to take events of all sorts, and be responsible themselves for throwing away the events that they don't want to bother with.Edit: just to make things clearer with an example,