- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
没有-6ren"> 没有-我有一个接口(interface),其中包含 T 的数组(或列表)和一些元数据。 interface DataWithMetadata { val someMetadata: Int -6ren">
我有一个接口(interface),其中包含 T 的数组(或列表)和一些元数据。
interface DataWithMetadata<T> {
val someMetadata: Int
fun getData(): Array<T>
}
如果我编写接口(interface)的最简单实现,我会在 emptyArray()
上得到一个编译错误:“Cannot use T as a reified type parameter. Use a class instead.”
class ArrayWithMetadata<T>(override val someMetadata: Int): DataWithMetadata<T> {
private var myData: Array<T> = emptyArray()
override fun getData(): Array<T> {
return myData
}
fun addData(moreData: Array<T>) {
this.myData += moreData
}
}
但是,如果我将接口(interface)和实现都更改为列表,则不会出现编译时问题:
interface DataWithMetadata<T> {
val someMetadata: Int
fun getData(): List<T>
}
class ListWithMetadata<T>(override val someMetadata: Int): DataWithMetadata<T> {
private var myData: List<T> = emptyList()
override fun getData(): List<T> {
return myData
}
fun addData(moreData: Array<T>) {
this.myData += moreData
}
}
我怀疑我的问题中有一些关于 Kotlin 泛型的有趣类(class)。谁能告诉我编译器在幕后做了什么以及为什么 Array 失败但 List 没有?有没有一种惯用的方法可以在这种情况下编译 Array 实现?
额外问题:我使用 Array over List 的唯一原因是我经常看到 Kotlin 开发人员偏爱数组。是这样吗,如果是,为什么?
最佳答案
看emptyArray()
的声明在 kotlin 标准库 (jvm) 中,我们注意到 reified
类型参数:
public inline fun <reified @PureReifiable T> emptyArray(): Array<T>
reified
类型参数意味着你可以访问 T
的类在编译时,可以像 T::class
一样访问它.您可以阅读有关 reified
的更多信息Kotlin reference 中的类型参数.从 Array<T>
编译成 java T[]
,我们需要在编译时知道类型,因此 reified
范围。如果您尝试编写没有 reified
的 emptyArray() 函数关键字,你会得到一个编译器错误:
fun <T> emptyArray() : Array<T> = Array(0, { throw Exception() })
Cannot use T as a reified type parameter. Use a class instead.
现在,我们来看看emptyList()
的实现:
public fun <T> emptyList(): List<T> = EmptyList
这个实现不需要参数T
一点也不。它只返回内部对象 EmptyList
,它本身继承自 List<Nothing>
. kotlin 类型 Nothing
是 throw
的返回类型关键字并且是永远不存在的值 (reference)。如果方法返回 Nothing
, 相当于在那个地方抛出异常。所以我们可以放心使用Nothing
因为每次我们都会调用 EmptyList.get()
编译器知道这会返回异常。
额外问题:
来自Java和C++,我习惯了ArrayList
或 std::vector
更容易使用该数组。我现在使用 kotlin 几个月了,在编写源代码时,我通常看不到数组和列表之间有很大的区别。两者都有大量有用的扩展函数,它们的行为方式相似。然而,Kotlin 编译器处理数组和列表的方式非常不同,因为 Java 互操作性对 Kotlin 团队非常重要。我通常更喜欢使用列表,这也是我在你的情况下推荐的。
关于java - Kotlin 泛型 Array<T> 结果为 "Cannot use T as a reified type parameter. Use a class instead"但 List<T> 没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46869353/
我是一名优秀的程序员,十分优秀!