【问题标题】:Kotlin type inference failed - type mismatch "Found Array<*?>, Required Array<*>?"Kotlin 类型推断失败 - 类型不匹配“找到 Array<*?>, Required Array<*>?”
【发布时间】:2016-09-06 07:42:05
【问题描述】:

我遇到了 Kotlin 类型系统的问题。我在类范围内声明了如下变量:

var planets: ArrayList<Planet>? = null

在构造函数中,我尝试初始化数组,但遇到类型不匹配错误:

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

错误:

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

为什么会出现此错误,如何解决?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    至少有一颗行星 (earth, mars, saturn, jupiter, uranus, neptune, pluto) 是可空类型 Planet?,因此推断的 arrayListOf(earth, ...) 类型是 ArrayList&lt;Planet?&gt;

    由于ArrayList&lt;Planet&gt; 在类型Planet 上不是逆变的,它不能安全地赋值给ArrayList&lt;Planet?&gt;

    要解决问题,您可以:

    • 确保所有行星都是不可为空的类型Planet
    • 如果以上不可行改变

      var planets: ArrayList<Planet>? = null
      

      var planets = arrayListOf<Planet?>()
      
    • 过滤掉nullplanets,然后将结果集合分配给planets

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

    另一种让编译器满意的方法是让planets contravariant 像这样:

    var planets: ArrayList<in Planet>? = null
    

    附言。尽可能使用kotlin collection typesList&lt;T&gt;Set&lt;T&gt; 和相应的listOfsetOf,而不是Java 的对应项。

    【讨论】:

    • 您是否以某种方式通知了新的#kotlin 问题? :P
    • 如果你知道哪个星球可以为空,但你确定不是,你可以写planet!!
    【解决方案2】:

    列表中的行星类型为Planet?,而不是Planet。请检查一下。

    解决方法有以下三种:
    1. 将行星类型改为Planet.
    2. 将列表定义改为

    var planets: ArrayList<Planet?>? = null
    

    3。如果您确定它们不为空,则映射存在的行星

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

    2 号是最差的,我更喜欢 1 号,如果不可能的话,3 号作为解决方法。

    【讨论】:

      猜你喜欢
      • 2018-10-08
      • 1970-01-01
      • 2018-08-21
      • 2020-12-30
      • 2018-05-15
      • 2011-04-01
      • 2020-07-06
      • 2017-04-03
      • 2018-05-03
      相关资源
      最近更新 更多