Получить тип универсального во время выполнения в Kotlin - PullRequest
0 голосов
/ 02 марта 2019

Как я могу сделать это правильно?

Потому что это не работает.У меня 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>?

1 Ответ

0 голосов
/ 02 марта 2019

Этого можно добиться, используя встроенные функции с ограниченными типами .Таким образом, вы в основном на правильном пути, но ваш оператор when проверяет this (который в вашем коде является экземпляром SomeClass<T> против String::class, Char::class и т. Д. Вместо этого вам нужно сравнить сам класс.

Я бы порекомендовал иметь внутренний метод, который включает KClass<T> для включения, а затем общедоступную встроенную функцию reified, которая предоставляет 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<String>, вы можете просто сделать:

someClassString.defaultSerializer()

Причина разделения внутренних и открытых функций состоит в том, чтобы избежать встраиванияполный блок when везде, где он используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...