在Kotlin中使用通用输入参数声明函数文字
我不知道如何指定一个函数文字,其中的输入参数可以covary,使函数文字可以分配给它接受输入types的子types的函数。
我能想到的最简单的例子是我想要做这样的事情:
var f: (Number) -> Unit = { number: Number -> println(number) } f = {int: Int -> println(number) } // <-- this does not compile
这些声明不起作用:
var f: (in Number) -> Unit = {number: Number ->} // doesn't compile var f: (out Number) -> Unit = {number: Number ->} // doesn't compile var f: (N) -> Unit = {number: Number ->} // ridiculous
这是我真正想做的事情的背景。 我想创建一个简单的事件处理程序类。
这是我的Kotlin代码:
class EventHandler() { private val NO_OP = {event: Event -> } private val handlerMap = mutableMapOf<KClass, (Event) -> Unit>() // here is the problem declaration fun registerHandler( eventClass: KClass, handler: (E) -> Unit) { handlerMap[eventClass] = handler // this doesn't compile } fun handle(event: Event) = getHandler(event).invoke(event) fun getHandler(event: Event): (Event) -> Unit = handlerMap[event::class] ?: NO_OP }
handlerMap[eventClass] = handler
不会编译,因为handlerMap
接受值为(Event) -> Unit
, handler
的types是(E) -> Unit
其中E
是扩展Event的types参数( )。
错误消息是:
Events.kt:[18,9] Type inference failed: Cannot infer type parameter V in operator inline fun MutableMap.set(key: K, value: V): Unit None of the following substitutions receiver: MutableMap<KClass, (Event) -> Unit> arguments: (KClass,(Event) -> Unit) receiver: MutableMap<KClass, (E) -> Unit> arguments: (KClass,(E) -> Unit) can be applied to receiver: MutableMap<KClass, (Event) -> Unit> arguments: (KClass,(E) -> Unit)
我正在使用kotlin-maven-plugin:1.1-M03。
好的,我之前没有想到这一点,但是看起来你可以将Function函数转换为文字types。
换句话说,你可以做到这一点
var f: (Number) -> Unit = { number: Number -> println(number) } f = {int: Int -> println(number) } as (Number) -> Unit
对于我的实际用例,我会使registerHandler
函数看起来像这样:
fun registerHandler(eventClass: KClass, handler: (E) -> Unit) { handlerMap[eventClass] = handler as (Event) -> Unit }