1

EventBus在我的 Scala 项目中使用 Guava。

我有一个像这样的参数化事件:

class MyEvent[T]

还有一个简单的事件监听器:

class MyEventListener {

    @Subscribe
    def onStringEvent(event: MyEvent[String]) {
        println("String event caught")
    }

    @Subscribe
    def onIntEvent(event: MyEvent[Int]) {
        println("Int event caught")
    }

}

我可以创建 my com.google.common.eventbus.EventBus、 registerMyEventListener和触发事件:

val eventBus = new EventBus
eventBus.register(new MyEventListener)
eventBus.post(new MyEvent[String])

但是,正如您可能已经猜到的那样,两者都onStringEventonIntEvent调用。问题是 Java/Scala 的类型擦除会在运行时删除参数类型,并且两个订阅在 Guava 中都显示为event: MyEvent.

好的,我的问题:

由于擦除,以这种方式对不同类型的 Guava 事件使用相同的 Event 对象在 Java 中是不可能的,在 Scala 中也是不可能的。然而,Scala 被证明有许多很好的方法来规避 Java 的擦除问题。有没有人看到另一种方法来实现这一点,也许使用一些 Scala 魔法?

4

1 回答 1

4

问题出在 Guava 中:它看不到类型参数,因此无法区分这两种方法。唯一可能的解决方案是为每种类型创建一个新类。

这真的很容易:

class MyEvent[T] protected () { /* Your methods here */ }
class MyEventInt extends MyEvent[Int] {}
class MyEventString extends MyEvent[String] {}

然后每当您需要在代码中执行任何操作时,只需使用MyEvent[Int]. 但番石榴至少需要这么多样板文件。

请注意,我已将MyEvent[T]构造函数设置为受保护,因此您必须实例化其中一个退化的类。我不确定这是否适用于您的用例;我会假设是这样。你也可以解决这个问题(使用类型类),但它增加了更多样板。

于 2012-12-27T22:11:35.177 回答