繁体   English   中英

Kotlin 泛型类型参数不匹配:推断类型为“非空”,但预期为“可为空”

[英]Kotlin generic type parameter mismatch: infered type is 'non-null' but 'nullable' was expected

我有一个带参数 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

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

这是与方差相关的错误:如果将T LiveData<Int> out变量,则LiveData<Int?>只能是LiveData<Int>的子类型:

class LiveData<out T>

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

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

但最好简单地更改add签名以接受LiveData<T>除非这是不需要的。

您可以将Wrapper类声明修复为以下内容

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

我换了T? TLiveData类型参数。 这样你就可以同时拥有Wrapper<Int>Wrapper<Int?>类型。

Kotlin 告诉可空类型(例如Int? )和不可空类型,例如Int 您可以查看文章了解更多详情: https : //kotlinlang.org/docs/reference/null-safety.html

上一个答案中建议使用第二个选项来使用方差。 可能无法用于LiveData类/接口的某些实现。
https://kotlinlang.org/docs/reference/generics.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM