Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics Kotlin泛型未正确转换_Generics_Kotlin_Casting - Fatal编程技术网

Generics Kotlin泛型未正确转换

Generics Kotlin泛型未正确转换,generics,kotlin,casting,Generics,Kotlin,Casting,我有一个抽象类(MessageHandlerAdapter),它接受一个泛型类型(p),然后用于键入传递到其函数之一的值: abstract class MessageHandlerAdapter<in P : Any> { abstract fun canHandle(): MessageType abstract fun handle(payload: P) } 但是,如果将其与列表一起使用,则会收到错误消息类型推断失败。预期类型不匹配:必需:Listfound

我有一个抽象类(
MessageHandlerAdapter
),它接受一个泛型类型(
p
),然后用于键入传递到其函数之一的值:

abstract class MessageHandlerAdapter<in P : Any> {
    abstract fun canHandle(): MessageType
    abstract fun handle(payload: P)
}
但是,如果将其与
列表
一起使用,则会收到错误消息
类型推断失败。预期类型不匹配:必需:Listfound:List
在我试图传递的列表上:

lateinit var stringHandler: MessageHandlerAdapter<String>
lateinit var  intHandler: MessageHandlerAdapter<Int>
val messageHandlerStrategy = MessageHandlerStrategy(listOf(stringHandler, intHandler))

class MessageHandlerStrategy(
    private val messageHandlers: List<MessageHandlerAdapter<Any>>
) {
    private val strategies = messageHandlers.map { Pair(it.canHandle(), it) }.toMap()

    fun handle(message: Message<Any>) {
        val strategy = strategies[message.type]
            ?: throw IllegalArgumentException>(IllegalArgumentException("No MessageHandler for message of type ${message.type}"))

        strategy.handle(message.payload)
    }
}
lateinit var stringHandler:MessageHandlerAdapter
lateinit变量intHandler:MessageHandlerAdapter
val messageHandlerStrategy=messageHandlerStrategy(listOf(stringHandler,intHandler))
类messagehandler策略(
私有val消息处理程序:列表
) {
private val strategies=messageHandlers.map{Pair(it.canHandle(),it)}.toMap()
有趣的手柄(信息:信息){
val策略=策略[消息.类型]
?:抛出IllegalArgumentException>(IllegalArgumentException(“没有类型为${message.type}的消息的MessageHandler”))
策略.句柄(消息.有效载荷)
}
}

我还尝试将
messagehandleadapter
的签名更改为
抽象类messagehandleadapter{…
但这没有任何区别。

因为您有不同类型的
MessageHandlerAdapter
s,您的列表必须使用星号投影
,但这使得列表中的对象对于调用任何以类型为参数的函数都毫无用处。您必须将检索到的适配器转换为无法对其调用类型化函数

首先,我将消除MessageType类,只使用有效负载类型的KClass来简化我们如何处理它,并消除创建MessageType和有效负载类型不匹配的消息的可能性:

abstract class MessageHandlerAdapter<P : Any>(val payloadType: KClass<P>) {
    abstract fun handle(payload: P)
}

// Just an example, don't know what your Message class has
data class Message<P : Any>(val payloadType: KClass<P>, val payload: P)

感谢您的回答。消息是
接口消息{val payload:P,val type:MessageType}
MessageType
只是一个枚举,用于定义消息是什么(更新X、执行操作Y等).最后,我从你的回答中得到的是,我们必须进行某种类型的转换。我只是很惊讶,在Java中可以应用
MessageHandler
,这很高兴,但在Kotlin中,没有等效的。我理解为什么,只是需要一些时间来适应我的猜测。
abstract class MessageHandlerAdapter<P : Any>(val payloadType: KClass<P>) {
    abstract fun handle(payload: P)
}

// Just an example, don't know what your Message class has
data class Message<P : Any>(val payloadType: KClass<P>, val payload: P)
class MessageHandlerStrategy(
    private val messageHandlers: List<MessageHandlerAdapter<*>>
) {

    fun <P : Any> handle(message: Message<P>) {
        val strategy = messageHandlers.find { it.payloadType == message.payloadType }
            ?: throw IllegalArgumentException("No MessageHandler for message of type ${message.payloadType}")

        @Suppress("UNCHECKED_CAST")
        (strategy as MessageHandlerAdapter<Any>).handle(message.payload)
    }
}