首页 > 解决方案 > Kotlin 泛型类型参数不匹配:推断类型为“非空”但预期为“可空”

问题描述

我有带有参数 T 的数据包装类。function这个类中有通用容器,nullable类型为:T?(例如 LiveData<T?>)

class Wrapper<T> {
   fun add (data: LiveData<T?>) {
    // ...
   }
}

在这个地方我真的需要这样的类型。当我尝试使用此方法并传递非空类型参数时:

class Program {
   fun get() {
      // some generic container, e.g. LiveData
      val data: LiveData<Int> = MutableLiveData()
      val wrapper = Wrapper<Int>()
      wrapper.add(data)
                  ^^^^ error
   }
}

这是“类型不匹配”错误:图片链接

Type mismatch: inferred type is LiveData<Int> but LiveData<Int?> was expected

如何处理?如何智能地将泛型类型参数从非空转换为可空?

标签: genericskotlin

解决方案


这是一个与方差有关的错误:如果你创建一个变量LiveData<Int?>,它只能是一个子类型:LiveData<Int>Tout

class LiveData<out T>

一般规则是:当一个类的类型参数TC声明为 out 时,它可能只出现在 的成员中的 out 位置C,但作为回报C<Base>可以安全地成为 的超类型C<Derived>

用“聪明的话”他们说类C在参数中是协变的T,或者T是协变类型参数。您可以将其C视为 's 的生产者T,而不是 T's 的消费者。

但最好将add签名简单地更改为接受LiveData<T>,除非这是不希望的。


推荐阅读