[英]Returning concrete class that inherits generic class in Kotlin
I'm trying to do the following:我正在尝试执行以下操作:
inline fun <reified T> getMapper(klass: Class<T>): RFMFunction<T, Event> =
when (klass) {
MClick::class.java -> MClickMapper
else -> { throw RuntimeException("Unknown event type: $klass") }
}
with:和:
object MClickMapper : RFMFunction<MClick, Event>()
but Kotlin doesn't recognize that MClickMapper
is a subclass of RFMFunction<MClick, Event>
.但 Kotlin 无法识别MClickMapper
是RFMFunction<MClick, Event>
的子类。
I tried to add a cast as RFMFunction<MClick, Event>
in the when
, but that didn't work.我尝试在when
中将演员表添加as RFMFunction<MClick, Event>
,但这没有用。
The error I get is:我得到的错误是:
Type mismatch.
Required: RFMFunction<T, Event>
Found: ClickMapper
Is there a way to do that?有没有办法做到这一点?
Thanks!谢谢!
Kotlin doesn't recognize that MClickMapper is a subclass of RFMFunction<MClick, Event> Kotlin 无法识别 MClickMapper 是 RFMFunction<MClick, Event> 的子类
That is not entirely correct.这并不完全正确。 The error is Type mismatch: inferred type is MClickMapper but RFMFunction<T, Event> was expected
.错误是Type mismatch: inferred type is MClickMapper but RFMFunction<T, Event> was expected
。
So in fact, Kotlin refuses to consider MClickMapper
as a subclass of RFMFunction<T, Event>
, because T
is provided by the caller of your function. The compiler doesn't go as far as knowing that klass == MClick::class.java
means that T == MClick
.所以实际上,Kotlin 拒绝将MClickMapper
视为RFMFunction<T, Event>
的子类,因为T
是由 function 的调用者提供的。编译器不知道klass == MClick::class.java
意味着那T == MClick
。 You could technically use an unchecked cast here (since you know more than the compiler), but it should be a cast to RFMFunction<T, Event>
(not RFMFunction<MClick, Event>
).从技术上讲,您可以在此处使用未经检查的强制转换(因为您比编译器了解的更多),但它应该强制转换为RFMFunction<T, Event>
(而不是RFMFunction<MClick, Event>
)。 And then you can suppress the unchecked cast warning.然后你可以抑制未经检查的投射警告。
Also, as a side note, why do you use both a KClass
and a reified
type argument?另外,作为旁注,您为什么同时使用KClass
和reified
类型参数? If you reify T
, you don't need the explicit KClass
:如果您具体化T
,则不需要明确的KClass
:
@Suppress("UNCHECKED_CAST")
inline fun <reified T> getMapper(): RFMFunction<T, Event> = when (T::class) {
MClick::class -> MClickMapper as RFMFunction<T, Event>
else -> throw RuntimeException("Unknown event type: ${T::class}")
}
However, this solution is not great , because you kinda hardcode twice the relationship between MClickMapper
and MClick
(in the when
AND in the inheritance hierarchy), which means if those 2 places go out of sync you can have problems that won't be seen at compile time.然而,这个解决方案不是很好,因为你有点硬编码MClickMapper
和MClick
之间的关系(在when
和 inheritance 层次结构中),这意味着如果这两个地方 go 不同步,你可能会遇到看不到的问题在编译时。 It would be better to use the type information to create the mapping dynamically, so you have the mapping harcoded in a single place.最好使用类型信息动态创建映射,这样您就可以在一个地方对映射进行硬编码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.