In Java we can do this Events.handler(Handshake.class, hs -> out.println(hs));

In Kotlin however I am trying to replicate the behavior to replace this:

Events.handler(Handshake::class, object : EventHandler<Handshake> {
    override fun handle(event: Handshake) {
        println(event.sent)
    }
})

With a more convenient:

Events.handler(Handshake::class, EventHandler<Handshake> { println(it.sent) })

For some reason in reference to EventHandler:

enter image description here

不过,更可取的是,我想使用更简短的内容,比如:

Or use the advertised feature to use the method like this: Events.handler(Handshake::class) { println(it.sent) }

这是我的Events件物品:

import java.util.*
import kotlin.reflect.KClass

object Events {

    private val map = HashMap<Class<*>, Set<EventHandler<*>>>()

    fun <T : Any> handler(eventType: KClass<T>, handler: EventHandler<T>) {
        handler(eventType.java, handler)
    }

    fun <T> handler(eventType: Class<T>, handler: EventHandler<T>) = handlers(eventType).add(handler)

    fun post(event: Any) = handlers(event.javaClass).forEach { it.handle(event) }

    operator fun plus(event: Any) = post(event)

    private fun <T> handlers(eventType: Class<T>): HashSet<EventHandler<T>> {
        var set = map[eventType]
        if (set == null) {
            set = HashSet<EventHandler<*>>()
            map.put(eventType, set)
        }
        return set as HashSet<EventHandler<T>>
    }

}

我的EventHandler界面:

@FunctionalInterface
interface EventHandler<T> {

    fun handle(event: T)

}

推荐答案

自从@andrey breslav发布答案以来,Kotlin身上发生了很多好事.他提到:

就是那个柯特林only does SAM-conversion for functions defined in Java.因为Events.handler是在Kotlin中定义的,所以SAM-Conversions 不适用于它.

Well, that's no longer the case for Kotlin 1.4+. It can use SAM-conversion for Kotlin functions if you mark an interface as a "functional" interface:

// notice the "fun" keyword
fun interface EventHandler<T> {
    fun handle(event: T)
}

你可以在这里读YouTrack的票:https://youtrack.jetbrains.com/issue/KT-7770.还有一种解释解释,为什么Kotlin需要一个标记来表示这样的接口,而不像Java(@FunctionalInterface只是信息性的,has no effect on the compiler是).

Kotlin相关问答推荐

Lambda和普通Kotlin函数有什么区别?

为什么onEach不是挂起函数,而Collect是?

关键字';在When Kotlin When-语句中

如何接受任何派生类KClass

多模块Kotlin项目中的FreeFair

如何通过更改现有数据类型来执行Android房间数据库迁移?

Webpack 配置未应用于 kotlin 多平台react 项目

内联函数导致单元测试代码覆盖率报告出错

使用 Kotlin 创建新目录,Mkdir() 不起作用

如何在顶级函数中使用 koin 注入依赖项

Firebase 权限被拒绝

Kotlin中的测试无法访问受保护(protected)的方法

main函数和常规函数有什么区别?

如何在Kotlin中创建填充空值的通用数组?

使用范围的稀疏sparse值列表

Kotlin reflect proguard SmallSortedMap

Kotlin协程无法处理异常

我应该在哪里调用 MobileAds.initialize()?

java.lang.NoClassDefFoundError:解析失败:Lkotlin/time/MonoClock

Kotlin for assertThat(foo, instanceOf(Bar.class))