首页 > 解决方案 > Kotlin - 可为空的接收器扩展不接受不可为空的等价物

问题描述

考虑以下示例:

class Foo<T>

fun <T> Foo<Iterable<T>?>.bar(i: Iterable<T>) {
    ...
}

Foo有一个扩展方法,bar它需要一个接收者Iterable<T>?

考虑以下用例:

val x = listOf(123, 456)
val f = Foo<Iterable<Int>>()

f.bar(x)

编译器错误f

类型不匹配

必需:Foo<Iterable<Int>?>

找到:Foo<Iterable<Int>>

我可以理解这不起作用,试图将可空类型传递给不可空接收器,但我不明白为什么我不能将不可空类型传递给可空接收器。

本质上我想说“接收器可能为空,但在这种情况下,我可以保证它不是”

关于如何解决这个问题的任何想法,所以扩展方法将允许可空和不可空类型?

注意:我无法更改val f = Foo<Iterable<Int>>为,val f = Foo<Iterable<Int>?>因为这是根据属性的类型自动决定的。

标签: kotlincovariance

解决方案


只需添加out修饰符,它将起作用:

class Foo<out T>

我们使用out修饰符来表示协方差(类似于 Java 中的“? extends T”)。协变- 是将泛型类型参数从一个类更改为其父类之一的能力,即分配List<String>List<Any>.

这是有关泛型的文档。


推荐阅读