返回继承Kotlin中泛型类的具体类

pnwntuvh  于 2023-02-05  发布在  Kotlin
关注(0)|答案(1)|浏览(111)

我正在努力做到以下几点:

inline fun <reified T> getMapper(klass: Class<T>): RFMFunction<T, Event> =
    when (klass) {
      MClick::class.java -> MClickMapper
      else -> { throw RuntimeException("Unknown event type: $klass") }
    }

与:

object MClickMapper : RFMFunction<MClick, Event>()

但是Kotlin没有意识到MClickMapperRFMFunction<MClick, Event>的子类。
我尝试在when中添加强制转换as RFMFunction<MClick, Event>,但没有成功。
我得到的错误是:

Type mismatch.
Required: RFMFunction<T, Event>
Found: ClickMapper

有办法做到吗?
谢谢!

goqiplq2

goqiplq21#

Kotlin无法识别MClickMapper是RFMFunction〈MClick,Event〉的子类
这不完全正确。错误是Type mismatch: inferred type is MClickMapper but RFMFunction<T, Event> was expected
所以实际上,Kotlin拒绝将MClickMapper视为RFMFunction<T, Event>的子类,因为T是由函数的 caller 提供的,编译器并不知道klass == MClick::class.java意味着T == MClick。(因为您知道的比编译器多),但是它应该是一个到RFMFunction<T, Event>(而不是RFMFunction<MClick, Event>)的强制转换,然后您可以取消未检查的强制转换警告。
另外,顺便提一句,为什么要同时使用KClassreified类型参数呢?如果要具体化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}")
}

但是,此解决方案并不好,因为您需要将MClickMapperMClick之间的关系硬编码两倍(在继承层次结构中的when AND中),这意味着如果这两个位置不同步,您可能会遇到编译时看不到的问题。最好使用类型信息来动态创建Map,这样你就可以把Map编码在一个地方。

相关问题