Kotlin类型推断失败 – 类型不匹配“Found Array <*?>,必需数组<*>?”
我遇到了Kotlin类型系统的问题。 我在类的范围内声明了如下的变量:
var planets: ArrayList<Planet>? = null
并在构造函数中尝试初始化数组,但遇到类型不匹配错误:
planets = arrayListOf(earth, mars, saturn, jupiter, uranus, neptune, pluto)
错误:
Required: ArrayList<Planet>? Found: ArrayList<Planet?>
为什么我得到这个错误,我该如何解决?
至少有一个行星( earth, mars, saturn, jupiter, uranus, neptune, pluto
)是可以为空的Planet?
因此arrayListOf(earth, ...)
的推断类型是ArrayList<Planet?>
。
由于ArrayList<Planet>
在类型Planet
上不是逆变,所以不能安全地赋值为ArrayList<Planet?>
。
要解决这个问题,你可以:
- 确保所有的行星都是不可空
Planet
-
如果以上是不可行的改变
var planets: ArrayList<Planet>? = null
至
var planets = arrayListOf<Planet?>()
-
滤除
null
行星,然后将结果集合分配给planets
:planets = arrayListOf(*arrayListOf(earth, ...).filterNotNull().toTypedArray())
让编译器感到高兴的另一种方式是使planets
逆转如此:
var planets: ArrayList<in Planet>? = null
PS。 尽可能使用kotlin集合类型 List<T>
, Set<T>
和相应的listOf
, setOf
而不是Java的对应。
列表中的Planet?
有Planet?
,而不是Planet
。 请检查一下。
修复有三种方法:
1.将行星类型更改为Planet
。
2.将列表定义更改为
var planets: ArrayList<Planet?>? = null
3.如果你确定它们不是null,则映射存在的行星
planets = ArrayList(listOf(earth, ... ).map { it!! }) // or safer way planets = ArrayList(listOf(earth, ... ).filterNotNull())
数字2是最差的,我更喜欢数字1,如果不可能,数字3是解决方法。