下面是我的情况的最起码的例子:
class Foo<T>(val list: List<Any>) {
init {
list.filterIsInstance<T>().forEach { ... } // error
}
}
当然,这并不能编译:
Cannot use 'T' as reified type parameter. Use a class instead.
这种情况的惯用解决办法是什么?这听起来像是编译器在建议一个KClass<T>
作为构造函数参数,但是这种用法是什么样子的呢?
发布于 2020-03-06 10:57:17
这里有很多问题。首先,您有一个指定的错误,因为您的类T
的参数类型Foo
没有具体化。因此,您需要声明类型参数的关键字reified
。但是,为了能够做到这一点,您需要一个inline
函数(因为JVM的限制,Kotlin应该支持)。问题是,在Kotlin中,不能使构造函数成为inline
。
最接近您所需要的是以下内容:
class Foo<T>(val list: List<T>) {
init {
list.forEach { println(it) }
}
companion object {
inline fun <reified T> create(list: List<Any>): Foo<T> {
return Foo(list.filterIsInstance<T>())
}
}
}
以上假设您只需要从列表中获取作为某个类的实例的所有元素,并且只使用Foo
类中的这些元素。
UPDATE:尽管您希望具体化Foo
实例上的类型参数,但这在Kotlin中是不可能的(由于JVM的限制,正如上面所指定的)。
所以您需要确保在创建时传递的类型是相同的吗?很好。那么,除了指定一个额外的参数之外,没有其他方法:
class Foo<T>(val list: List<Any>, `class`: Class<T>) {
init {
list.filter { `class`.isInstance(it) }.forEach { println(it) }
}
}
您没有指定要对所获得的列表做什么,以及为什么需要严格相同的类型,但我个人不去费心地使用第一个变体。
https://stackoverflow.com/questions/60554185
复制相似问题