kotlin - 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>?>
因为这是根据属性的类型自动决定的。
解决方案
只需添加out
修饰符,它将起作用:
class Foo<out T>
我们使用out
修饰符来表示协方差(类似于 Java 中的“? extends T”)。协变- 是将泛型类型参数从一个类更改为其父类之一的能力,即分配List<String>
给List<Any>
.
这是有关泛型的文档。
推荐阅读
- python - 将(行)函数应用于 DataFrame 会更改列类型
- python - 如何更快地将更大的 .sql 文件执行到数据库?
- ruby - 从 Fastlane 启动文本编辑器?
- c# - .NET Core - 在哪里保存由多个 Repos/API 共享的模型?
- javascript - 有没有办法在 JS 中使用括号表示法调用存储为属性的函数?
- python - Selenium 自动化使用 Python 和 Selenium 在 An ul 中选择一个 li 菜单项
- javascript - 自定义 Swiper.js 进度条
- c# - 强制 Teamcity 忽略 .net 项目中的工具版本
- python - 如何拆分、发送和合并 UDP?
- java - 在Java中是否有数据类型的数据类型?