最近我遇到了一个问题,我有一个函数必须返回 I
的数组。 s,以枚举的所有值的形式E
, 与 E
实现接口(interface)I
,我想到的每个代码编译器都提示类型不匹配:
Error:(x, x) Kotlin: Type mismatch: inferred type is Array<E> but Array<I> was expected
一个最小的例子:
interface I {}
enum class E: I {
A, B, C;
}
fun getMoreInterfaces(): Array<I> {
return E.values()
}
尝试分配
E.values()
时会发生这种情况。到 Array<I>
类型的变量我很肯定这应该是可能的,因为
E
实现 I
.我在测试时想到的另一件事是,当这样使用时它工作得很好:
interface I {}
enum class E: I {
A, B, C;
}
fun getMoreInterfaces(): Array<I> {
return arrayOf(E.A, E.B, E.C)
}
我在这个话题上做了很多搜索,但没有运气(也许我选择了错误的方式来描述它?)
最佳答案
在 Kotlin 中,与 Java 不同,Array<T>
在 T
上是不变的,所以,对于 E
它是 I
的子类型, Array<E>
和 Array<I>
不是彼此的子类型。见:Variance .
鉴于 Array<T>
types 还存储项目类型,不能完全受制unchecked casts ,解决此问题的最佳方法是创建一个单独的数组。
您可以通过手动创建一个数组并用项目填充它来做到这一点,例如在您的示例中(或使用构造函数 Array(n) { ... }
),或使用 .toTypedArray()
应用于数组的列表表示( .asList()
):
fun getMoreInterfaces(): Array<I> {
return E.values().asList().toTypedArray()
}
(runnable sample)
但基本上,您可以使用
List<I>
如果您不在性能关键代码中,这对于 Kotlin 来说比使用数组更惯用,而且也更简单。另见:Difference between List and Array types in Kotlin
关于Kotlin:如果 E 是实现接口(interface) I 的枚举类,则从返回类型为 Array<I> 的函数返回 Array<E>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54200855/