Kotlin:使用lambda代替function界面?
在Java中,我们可以这样做Events.handler(Handshake.class, hs -> out.println(hs));
但是在Kotlin中,我试图复制这个行为来取代这个:
Events.handler(Handshake::class, object : EventHandler { override fun handle(event: Handshake) { println(event.sent) } })
用更方便:
Events.handler(Handshake::class, EventHandler { println(it.sent) })
出于某种原因参考EventHandler
:
更好的是,但是我想使用更短的东西,像这样: Events.handler(Handshake::class, { println(it.sent) })
或者使用广告的function来使用这样的方法: 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 handler(eventType: KClass, handler: EventHandler) { handler(eventType.java, handler) } fun handler(eventType: Class, handler: EventHandler) = handlers(eventType).add(handler) fun post(event: Any) = handlers(event.javaClass).forEach { it.handle(event) } operator fun plus(event: Any) = post(event) private fun handlers(eventType: Class): HashSet<EventHandler> { var set = map[eventType] if (set == null) { set = HashSet<EventHandler>() map.put(eventType, set) } return set as HashSet<EventHandler> } }
和我的EventHandler
接口:
@FunctionalInterface interface EventHandler { fun handle(event: T) }
假设下面,你真的需要EventHandler
作为一个单独的接口(例如Java互操作)。 如果你不这样做,你可以简单地使用一个types别名(自Kotlin 1.1以来):
typealias EventHandler = (T) -> Unit
在这种情况下,一个简单的lambda将立即工作。
但是如果你不想使用types别名,问题依然存在。 Kotlin只对Java中定义的函数进行SAM转换。 由于Events.handler
是在Kotlin中定义的,所以SAM转换不适用于它。
为了支持这个语法:
Events.handler(Handshake::class, EventHandler { println(it.sent) })
你可以定义一个名为EventHandler
的函数:
fun EventHandler(handler: (T) -> Unit): EventHandler = object : EventHandler { override fun handle(event: T) = handler(event) }
为了支持这个语法:
Events.handler(Handshake::class, { println(it.sent) })
或这个:
Events.handler(Handshake::class) { println(it.sent) }
您需要重载handler
函数来取代EventHandler
的函数:
fun Events.handler(eventType: Class , handler: (T) -> Unit) = EventHandler(handler)
注意:当未来版本的Kotlin具有types别名时,不需要EventHandler
接口,因为它将被替换为types(T) -> Unit
的命名别名(T) -> Unit
- JavaCodeStyleManager.getInstance(project).shortenClassReferences()不起作用
- IntelliJ运行vs运行jar,带有Social Oauth2的Springboot Kotlin,Multi模块Gradle项目
- 在intellij 16中创建Android应用时,Gradle同步失败
- 如何在IntelliJ IDEA中忽略Kotlin的所有警告?
- 在intellij中运行并执行jar时的微妙差异
- 如何为TestNG Kotlin项目添加gradle支持?
- IntelliJ:Kotlin错误导致鼠标闪烁和代码中的错误
- IntelliJ社区找不到Web应用程序工件来生成WAR
- 在IntelliJ中Kotlin未解决的参考