我有一个带有参数T的数据包装器类。此类中有function
,具有 generic 容器,其类型为nullable
:T? (例如LiveData
class Wrapper<T> {
fun add (data: LiveData<T?>) {
// ...
}
}
在这个地方,我确实需要这种类型。 当我尝试使用此方法并传递非null类型的参数时:
class Program {
fun get() {
// some generic container, e.g. LiveData
val data: LiveData<Int> = MutableLiveData()
val wrapper = Wrapper<Int>()
wrapper.add(data)
^^^^ error
}
}
这是“类型不匹配”错误:image link
Type mismatch: inferred type is LiveData<Int> but LiveData<Int?> was expected
如何处理?如何将通用类型参数从非null强制转换为可空值?
答案 0 :(得分:1)
这是与variance有关的错误:如果将LiveData<Int?>
设为LiveData<Int>
变量,T
只能是out
的子类型:
class LiveData<out T>
一般规则是:当类
T
的类型参数C
为 声明为“已淘汰”,则只能在C
的成员中排名第一, 但作为回报,C<Base>
可以安全地成为C<Derived>
的超类型。在“聪明的话”中,他们说类
C
在 参数T
,或T
是协变类型参数。您可以 认为C
是T
的生产者,而不是T
。
但是最好更改add
签名以接受LiveData<T>
,除非不希望这样做。
答案 1 :(得分:0)
您可以将Wrapper
类声明修改为以下内容
class Wrapper<T> {
fun add (data: LiveData<T>) {
// ...
}
我在T?
类型参数中将T
替换为LiveData
。这样您就可以同时拥有Wrapper<Int>
和Wrapper<Int?>
类型。
Kotlin从不可为空的类型(例如,Int?
)中告诉可为空的类型(例如Int
)。 LiveData
。您可以查看该文章以获取更多详细信息:
https://kotlinlang.org/docs/reference/null-safety.html
在上一个答案中建议第二个选项使用方差。 #define MACRO_NAME 8192
类/接口的某些实现可能无法使用。
https://kotlinlang.org/docs/reference/generics.html