如果你只有一个 KClass 对象,调用一个带有具体化类型参数的函数?
Calling a fun with reified type parameter if you just have a KClass object?
内联函数只能使用具体化的类型参数。因此,如果我想要 class 这样的参数,我需要这样的技巧:
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
吗` ?
例如在 Foo
我想添加这样的方法:
fun print(list: List<Alpha>) {
list.filterIsInstance<T>().forEach { print(it) }
}
但据我所知,没有办法从 clazz
到我可以在这里用作类型参数的东西。
是的,我知道 filterIsInstance
的一种形式需要 Class
所以我可以这样做:
list.filterIsInstance(clazz.java).forEach { print(it) }
然而,许多库包含的方法都未提供两种形式(显式 class 参数和具体化类型参数)。
例如杰克逊·科特林 Extensions.kt。实际上这不是一个很好的例子,因为非具体化的等价物都是单行的,但情况并非总是如此——然后你最终将具体化类型参数方法的实现解包到你的代码中。
不,因为这些函数是 inline
,它们在编译时内联
Class 或 KClass 在运行时使用反射
您可以使用一些技巧.. 就像同伴 class 一样,但这根本不需要 KClass<T>
.. 任何其他提供 [= 的通用参数的东西12=] 也适用于 reified
类型信息
PS:反射也不能可靠地帮助你,因为内联函数在运行时并不真正存在,正如它们的修饰符 inline
所解释的那样
除非我遗漏了一些东西,否则您可以在 reified T
的函数中用 T
做的所有事情都可以 转换为对 [=12 的使用=]:例如x is T
变为 clazz.isInstance(x)
,x as T
变为 clazz.cast(x)
,对具有具体化类型参数的其他函数的调用被递归翻译等。由于该函数必须是内联的,因此它使用的所有 API在呼叫站点可见,因此可以在那里进行翻译。
但据我所知,没有自动翻译的方法。
内联函数只能使用具体化的类型参数。因此,如果我想要 class 这样的参数,我需要这样的技巧:
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
吗` ?
例如在 Foo
我想添加这样的方法:
fun print(list: List<Alpha>) {
list.filterIsInstance<T>().forEach { print(it) }
}
但据我所知,没有办法从 clazz
到我可以在这里用作类型参数的东西。
是的,我知道 filterIsInstance
的一种形式需要 Class
所以我可以这样做:
list.filterIsInstance(clazz.java).forEach { print(it) }
然而,许多库包含的方法都未提供两种形式(显式 class 参数和具体化类型参数)。
例如杰克逊·科特林 Extensions.kt。实际上这不是一个很好的例子,因为非具体化的等价物都是单行的,但情况并非总是如此——然后你最终将具体化类型参数方法的实现解包到你的代码中。
不,因为这些函数是 inline
,它们在编译时内联
Class 或 KClass 在运行时使用反射
您可以使用一些技巧.. 就像同伴 class 一样,但这根本不需要 KClass<T>
.. 任何其他提供 [= 的通用参数的东西12=] 也适用于 reified
类型信息
PS:反射也不能可靠地帮助你,因为内联函数在运行时并不真正存在,正如它们的修饰符 inline
除非我遗漏了一些东西,否则您可以在 reified T
的函数中用 T
做的所有事情都可以 转换为对 [=12 的使用=]:例如x is T
变为 clazz.isInstance(x)
,x as T
变为 clazz.cast(x)
,对具有具体化类型参数的其他函数的调用被递归翻译等。由于该函数必须是内联的,因此它使用的所有 API在呼叫站点可见,因此可以在那里进行翻译。
但据我所知,没有自动翻译的方法。