2016-01-02 48 views
4

我剛剛回到Kotlin(從Java過渡),我注意到使用Consumer比聽起來更棘手。消費者在科特林扮演奇怪的角色

class EventBus(controller: Controller) { 
    private val consumerMap : MutableMap<KClass<out Event>, MutableSet<Consumer<out Event>>> = ConcurrentHashMap() 
    private val controller : Controller = controller 

    public fun <T : Event> register(clazz: KClass<T>, handler: Consumer<T>) { 
     consumerMap.getOrPut(clazz, { HashSet() }).add(handler) 
    } 

    public fun <T : Event> post(event : T) { 
     consumerMap[event.javaClass.kotlin]?.forEachIndexed { i, handler -> 
      controller.getLogger().trace("Firing handler ${i + 1} for event ${event.javaClass.name}") 
      handler.accept(event) 
     } 
    } 
} 

我試圖做一個簡單的類射擊死的基本事件,唯一的問題是根據的IntelliJ accept方法不存在。然而,當我試圖創建一個新的消費者並立即使用它時,accept方法就在那裏,並且正如預期的那樣工作。

http://pksv.co/go/myOeEvTE

有什麼我可能錯過或忽視?

回答

4

傻了。我的Java已經鑽了很長時間了。更換Consumer<out Event>(和其他Consumer使用)與(Event) -> Unit清除了一切!

任何有興趣的代碼:

class EventBus(controller: Controller) { 
    private val consumerMap : MutableMap<KClass<out Event>, MutableSet<(Event) -> Unit>> = ConcurrentHashMap() 
    private val controller : Controller = controller 

    public fun <T : Event> register(clazz: KClass<T>, handler: (T) -> Unit) { 
     consumerMap.getOrPut(clazz, { HashSet() }).add(handler as (Event) -> Unit) // hacky cast :-) 
    } 

    public fun <T : Event> post(event : T) { 
     consumerMap[event.javaClass.kotlin]?.forEachIndexed { i, handler -> 
      controller.getLogger().trace("Firing handler ${i + 1} for event ${event.javaClass.name}") 
      handler.invoke(event) 
     } 
    } 
}