generics - 在构造函数中使用模板类
问题描述
这是我的情况的最小示例:
class Foo<T>(val list: List<Any>) {
init {
list.filterIsInstance<T>().forEach { ... } // error
}
}
自然,这不会编译:
Cannot use 'T' as reified type parameter. Use a class instead.
这种情况的惯用解决方案是什么?听起来编译器建议将 aKClass<T>
作为构造函数参数,但这种用法是什么样的?
解决方案
这里有多个问题。首先,你有一个你指定的错误,因为T
你的类Foo
的 type 参数没有reified。因此,您需要reified
声明类型参数的关键字。但是,您需要一个inline
函数才能做到这一点(因为 JVM 的限制,Kotlin 应该支持)。问题是,你不能让构造函数inline
在 Kotlin 中。
最接近您需要的是以下内容:
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
类中的这些元素。
更新:即使您希望Foo
自己实例上的类型参数被具体化,这在 Kotlin 中根本不可能(如上所述,由于 JVM 限制)。
那么你需要确保创建时传递的类型是相同的吗?美好的。那么除了指定一个额外的参数之外别无他法:
class Foo<T>(val list: List<Any>, `class`: Class<T>) {
init {
list.filter { `class`.isInstance(it) }.forEach { println(it) }
}
}
您没有指定要对获得的列表做什么,以及为什么需要严格相同的类型,但我个人不会为此烦恼并使用第一个变体。
推荐阅读
- api - USPS Shipping API 标准邮政可加工标签
- powershell - 检查文件内容时 if 语句不起作用
- c# - 如何将 GridView 导出为 .xls
- css - Wordpress 突出主题:获得全宽 2 列组合
- python - 如何使用 tf.data.Dataset 和 tf.keras 做多输入多输出?
- c# - C# 将 CSV 文件上传到 Netezza
- python - 如何使用 Aws Lambda (python) 接收文件
- python - 将值传播到熊猫数据框中的列(枢轴)传感器事件中
- typo3 - Typo3 站点以信息亭模式运行
- java - 如何使用 TableModel 在 JTable 中渲染组件?