【问题标题】:Get type of generic at runtime in Kotlin在 Kotlin 运行时获取泛型类型
【发布时间】:2019-03-02 18:20:19
【问题描述】:

我怎样才能正确地做到这一点?

因为这不起作用。 我有一个null 结果总是class SomeClass<T>()

当我尝试做SomeClass<Int> 或类似的事情时,我得到一个空值,因为我不知道如何正确获取Generic 的类型。

我已经尝试在类中创建字段,但我想避免在此类中创建字段

    @Suppress("UNCHECKED_CAST")
fun <T : Any> SomeClass<T>.defaultSerializer(): KSerializer<T>? = when (this) {
    String::class -> StringSerializer
    Char::class -> CharSerializer
    Double::class -> DoubleSerializer
    Float::class -> FloatSerializer
    Long::class -> LongSerializer
    Int::class -> IntSerializer
    Short::class -> ShortSerializer
    Byte::class -> ByteSerializer
    Boolean::class -> BooleanSerializer
    Unit::class -> UnitSerializer
    else -> null
} as KSerializer<T>?

【问题讨论】:

标签: generics kotlin types


【解决方案1】:

您可以使用inline functions with reified types 实现此目的。所以你基本上走在正确的轨道上,但是你的 when 语句正在检查 this(在你的代码中是 SomeClass&lt;T&gt;String::classChar::class 等的一个实例。你需要比较类本身.

我建议有一个内部方法,它接受KClass&lt;T&gt; 来打开,然后是一个公共的内联具体化函数,它为内部方法提供KClass。例如:

@PublishedApi
internal fun <T : Any> SomeClass<T>.defaultSerializer(
    clazz: KClass<T>
): KSerializer<T>? = when (clazz) {
    String::class -> StringSerializer()
    Char::class -> CharSerializer()
    Double::class -> DoubleSerializer()
    Float::class -> FloatSerializer()
    Long::class -> LongSerializer()
    Int::class -> IntSerializer()
    Short::class -> ShortSerializer()
    Byte::class -> ByteSerializer()
    Boolean::class -> BooleanSerializer()
    Unit::class -> UnitSerializer()
    else -> null
} as KSerializer<T>?

inline fun <reified T: Any> SomeClass<T>.defaultSerializer(): KSerializer<T>? = 
    defaultSerializer(T::class)

然后,给定SomeClass&lt;String&gt; 的实例,您可以这样做:

someClassString.defaultSerializer()

将内部函数和公共函数分开的原因是避免在使用它的任何地方内联完整的 when 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多