我遇到了Kotlin的类型系统问题。我在类范围声明了变量:
var planets: ArrayList<Planet>? = null
并在构造函数中我尝试初始化数组但我遇到类型不匹配错误:
planets = arrayListOf(earth, mars, saturn, jupiter, uranus, neptune, pluto)
错误:
Required: ArrayList<Planet>?
Found: ArrayList<Planet?>
为什么我会收到此错误,如何解决?
答案 0 :(得分:8)
至少有一个行星(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
contravariant像这样:
var planets: ArrayList<in Planet>? = null
PS。尽可能使用kotlin collection types List<T>
,Set<T>
和相应的listOf
,setOf
而不是Java的对应方。
答案 1 :(得分:1)
列表中的行星的类型为Planet
,而不是Planet
。请检查一下。
修复有三种方法:
1.将行星类型更改为var planets: ArrayList<Planet?>? = null
2.将列表定义更改为
planets = ArrayList(listOf(earth, ... ).map { it!! })
// or safer way
planets = ArrayList(listOf(earth, ... ).filterNotNull())
3。如果确定它们不为空,则映射存在的行星
<xsl:for-each select="SUBSCRIBER_PROFILE_LIST/SUBSCRIBER_PROFILE_INFO[GROUP_NAME eq (group name list in a text file as input)]">
2号是最差的,我更喜欢1号,如果不可能,则3号作为变通方法。