Вызываете забаву с параметром reified type, если у вас просто есть объект KClass? - PullRequest
4 голосов
/ 28 марта 2019

Можно использовать только параметры типа reified со встроенными функциями. Поэтому, если мне нужен такой параметр для класса, мне понадобится такой трюк:

class Foo<T : Any>(private val clazz: KClass<T>) {
    companion object {
        inline fun <reified T: Any> create() = Foo(T::class)
    }
}

Затем я могу создать экземпляры Foo следующим образом:

val foo = Foo.create<Bar>()

В пределах Foo у меня есть доступ clazz, но у меня вопрос , могу ли я тогда использовать clazz, когда мне нужно вызвать методы, требующие параметра типа reified` ?

например. в Foo я бы хотел добавить такой метод:

fun print(list: List<Alpha>) {
    list.filterIsInstance<T>().forEach { print(it) }
}

Но, насколько я могу судить, нет способа получить от clazz что-то, что я могу использовать здесь в качестве параметра типа.

И да, я знаю, что есть форма filterIsInstance, которая принимает Class, поэтому я могу сделать:

list.filterIsInstance(clazz.java).forEach { print(it) }

Однако во многих библиотеках есть методы, в которых обе формы (явный параметр класса и параметр типа reified) не предоставлены.

например. Джексон Котлин Extensions.kt . На самом деле это не очень хороший пример, так как все эквиваленты без reified являются однострочными, но это не всегда так - тогда вы в конечном итоге распаковываете реализацию метода reified-type-parameter в ваш код.

Ответы [ 2 ]

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

Если я что-то упустил, все, что вы можете сделать с T в функции с reified T , может быть переведено на использование KClass: например, x is T становится clazz.isInstance(x),x as T становится clazz.cast(x), вызовы других функций с параметрами reified-типа преобразуются рекурсивно и т. Д. Так как функция должна быть встроенной, все ее API-интерфейсы видны на сайте вызова, поэтому перевод может быть выполнен там.

Но, насколько я знаю, автоматического способа сделать этот перевод не существует.

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

нет, потому что эти функции inline, они встроены во время компиляции и класс или KClass использует отражение во время выполнения

есть некоторые приемы, которые вы можете сделать ... как с классом-компаньоном, но для этого вообще не нужно KClass<T> ... все остальное, что предоставляет общий аргумент T, будет работать так же хорошо для reified введите информацию

PS: отражение также не может помочь вам надежно, потому что встроенные функции на самом деле не существуют во время выполнения, как объясняется их модификатором inline

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