2012-12-27 3 views
1

스칼라 프로젝트에 Guava의 EventBus을 사용하고 있습니다.스칼라 유형 삭제 (Guava EventBus 사용)

class MyEvent[T] 

그리고 간단한 이벤트 리스너 :

val eventBus = new EventBus 
eventBus.register(new MyEventListener) 
eventBus.post(new MyEvent[String]) 
: 나는 이벤트를, 내 com.google.common.eventbus.EventBus을 만들 MyEventListener을 등록하고 해고 할 수

class MyEventListener { 

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

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

} 

나는 매개 변수화 된 사건과 같이이

하지만 이미 짐작할 수 있듯이결과적으로3210 및 onIntEvent이 호출됩니다. 문제는 Java/Scala의 형식 지우기가 런타임에 매개 변수 유형을 삭제하고 두 구독이 모두 구아바에 event: MyEvent으로 표시된다는 것입니다.

좋아, 내 질문 :

인해 삭제에, 이러한 방식으로 구아바 다양한 종류의 이벤트에 동일한 이벤트 객체를 사용하여 자바에서 가능하지 않을 것입니다 및 스칼라 수 없습니다. 그러나 Scala는 Java의 삭제 문제를 우회하는 여러 가지 좋은 방법이 있음을 증명합니다. 다른 사람이 이것을 달성하기 위해 다른 방법을 보았습니까? 아마도 스칼라 마법을 사용했을 것입니다.

답변

4

문제는 구아바에 있습니다. 유형 매개 변수를 볼 수 없으므로 두 가지 방법을 구분하지 않습니다. 유일한 해결책은 각 유형에 대해 새 클래스를 만드는 것입니다. 정말 쉽게 할 수 있습니다

:

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

하고, 코드에서 작업을 수행 할 필요가 때마다 그럼 그냥 MyEvent[Int]를 사용합니다. 그러나 구아바에는 적어도이 많은 상용구가 필요합니다.

생성자 클래스를 인스턴스화해야하므로 MyEvent[T] 생성자를 보호했습니다. 그게 네 유스 케이스에서 작동 할 지 확신 할 수 없다. 나는 그렇게 추측 할 것이다. 또한 (클래스 유형을 사용하여)이를 해결할 수 있지만 더 많은 상용구가 추가됩니다.

+0

문법 중 일부를 제거하기 위해 implicits/typeclasses를 사용할 수 있다고 생각합니다. –

+0

@ DominicBou-Samra - 예가 있으면 게시 할 수 있습니다. MyEventString 인스턴스가 괜찮은 기본 케이스의 경우, 더 이상 상용구를 줄일 수있는 방법을 모르고 있습니다. 이미 generic-instantiation 경우에 대한 유형 클래스를 제안했지만 (어쩔 수없이 또 다른 상용구 AFAICT 라인을 추가합니다). –