Generics 类型失配;找到'Message',必需'T`
在我的代码中,我有一个方法Generics 类型失配;找到'Message',必需'T`,generics,kotlin,abstract-class,Generics,Kotlin,Abstract Class,在我的代码中,我有一个方法publishMessage需要从classMessage扩展类型。在此方法中,调用了publish,它需要T类型的message 这导致错误>类型不匹配;找到消息,需要T 这是否与T有关,它需要是使用该方法声明的类Message的扩展?我不明白为何不能这样做 在我看来,这种类型为T的参数可以是任何东西 我的班级 在我看来,这种类型为T的参数可以是任何东西 是的,它可以是任何类型,但编译器希望确保您的类型没有问题。因此,您必须像这样创建节点对象Node(),或者将pub
publishMessage
需要从classMessage
扩展类型。在此方法中,调用了publish
,它需要T
类型的message
这导致错误>类型不匹配;找到消息
,需要T
这是否与T
有关,它需要是使用该方法声明的类Message
的扩展?我不明白为何不能这样做
在我看来,这种类型为T
的参数可以是任何东西
我的班级
在我看来,这种类型为T的参数可以是任何东西
是的,它可以是任何类型,但编译器希望确保您的类型没有问题。因此,您必须像这样创建节点对象
Node()
,或者将publishMessage
方法签名更改为fun publishMessage(主题:字符串,类型:类,消息:T)
。在这种情况下,编译器可以保证类型安全,错误将消失。但编译器希望确保您的类型没有错误
为什么编译器会怀疑参数的有效性,而它可以是任何类型?嗯。。。它可以是对象创建期间的任何内容。但是,创建对象时,必须使用此特定类型。如果将类声明为Node,则可以创建Node类型的对象,也可以创建Node、Node等类型的对象,并且T类型的方法参数“message”将分别变为message、String或Any。如果您创建一个Node类型的对象,并尝试将字符串传递给该方法,该方法现在需要的是消息而不是字符串,那么您就有大麻烦了(这基本上是动态类型语言的大问题)@KlynerYou可能会想,“但是有一个参数,参数类型是Message,所以如果我把它传递给T,一切都会好起来。”。你绝对是对的!然而,从你的角度来看,这是可以的,而不是编译器的。在这个特定的时间点上,编译器会看到两种不同的类型,这就是为什么会出现错误。也许有一天它会知道你的代码是安全的,但今天它无法确定这一点@克林纳特汉克斯:太多了!现在我想它落地了。因此,T
指的是节点对象创建时使用的类型,该类型已定义,并且无法再为该特定对象更改。
fun <T : Message> publishMessage(topic: String, type: Class<T>, message: Message) {
val node = findOrCreateNode(topic, type)
node.publish(message) // Type mismatch; found `Message`, required `T` .
}
fun publish(message: T) {
// Implementation
}