Kotlin type inference failed - type mismatch “Foun

2020-03-01 17:42发布

问题:

I am encountering an issue with Kotlin's type system. I declared the variable as below at class scope:

var planets: ArrayList<Planet>? = null

and in the constructor I try to initialize the array but I am encountering a type mismatch error:

planets = arrayListOf(earth, mars, saturn, jupiter, uranus, neptune, pluto)

error:

Required: ArrayList<Planet>?
Found: ArrayList<Planet?>

Why am I getting this error and how do I fix it?

回答1:

At least one of the planets (earth, mars, saturn, jupiter, uranus, neptune, pluto) is of nullable type Planet? hence the inferred type of arrayListOf(earth, ...) is ArrayList<Planet?>.

Since ArrayList<Planet> is not contravariant on type Planet it cannot be safely to assigned with value ArrayList<Planet?>.

To resolve the problem you can:

  • make sure all planets are of not nullable type Planet
  • if the above is not feasible change

    var planets: ArrayList<Planet>? = null
    

    to

    var planets = arrayListOf<Planet?>()
    
  • filter out null planets and then assign the result collections to planets:

    planets = arrayListOf(*arrayListOf(earth, ...).filterNotNull().toTypedArray())
    

Another way to make the compiler happy is to make the planets contravariant like so:

var planets: ArrayList<in Planet>? = null

PS. Use kotlin collection types List<T>, Set<T> and corresponding listOf, setOf instead of Java's counterparts whenever possible.



回答2:

Your planets in the list have type Planet?, not Planet. Please, check it out.

To fix there are three ways:
1. Change planets type to Planet.
2. Change list definition to

var planets: ArrayList<Planet?>? = null

3. Map existed planets if you sure they are not null

planets = ArrayList(listOf(earth, ... ).map { it!! })
// or safer way
planets = ArrayList(listOf(earth, ... ).filterNotNull())

Number 2 is the worst one, I prefer number 1, if it is impossible, number 3 as workaround.



标签: kotlin