如果你只有一个KClass对象,那就用reified type参数调用一个有趣的东西?

问题描述 投票:4回答:2

只能使用具有内联函数的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,但我的问题是,当我需要调用需要reified类型参数的方法时,我可以使用clazz吗?

例如。在Foo中,我想添加一个这样的方法:

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

但据我所知,没有办法从clazz到我可以用作类型参数的东西。

是的,我知道有一种形式的filterIsInstance需要一个Class所以我可以这样做:

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

但是,许多库包含不提供两种形式(显式类参数和具体类型参数)的方法。

例如。杰克逊Kotlin Extensions.kt。实际上这不是一个很好的例子,因为非实现的等价物都是单行的,但情况并非总是如此 - 然后你最终将reified-type-parameter方法的实现解压缩到你的代码中。

generics kotlin kotlin-reified-type-parameters
2个回答
0
投票

不,因为这些函数是inline,它们在编译时倾向于Class或KClass在运行时使用反射

你可以做一些技巧..比如同伴类,但是根本不需要KClass<T> ..任何提供T通用参数的东西都可以用于reified类型信息

PS:反射也无法可靠地帮助你,因为内联函数在运行时并不存在,正如它们的修饰符inline所解释的那样


0
投票

除非我遗漏了某些东西,否则你在T函数中用reified T做的所有事情都可以转换为使用KClass:例如: x is T变为clazz.isInstance(x)x as T变为clazz.cast(x),具有reified类型参数的其他函数的调用被递归地翻译等。由于函数必须是内联的,所以它使用的所有API在调用站点都可见,因此可以在那里进行转换。

但据我所知,没有自动方式进行翻译。

© www.soinside.com 2019 - 2024. All rights reserved.