Kotlin type inference failed - type mismatch “Found Array<*?>, Required Array<*>?”

前端 未结 2 2168
甜味超标
甜味超标 2021-01-04 21:08

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

var planets: ArrayList? = null
<         


        
相关标签:
2条回答
  • 2021-01-04 21:52

    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.

    0 讨论(0)
  • 2021-01-04 22:09

    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.

    0 讨论(0)
提交回复
热议问题