Ani*_*ahu 4 generics covariance kotlin
这是一个代码,我很难理解为什么第一个编译而第二个不编译?
class Test11<T : Number> {
lateinit var test: MutableList<out T>.() -> Unit
}
fun main() {
val test: Test11<Int> = Test11<Int>()
val test2: Test11<out Number> = test
test.test.invoke(MutableList(3) { 55 }) // First
test2.test.invoke(MutableList(3) { 55 }) // Second
}
Run Code Online (Sandbox Code Playgroud)
第二个说MutableList<Nothing>是预料之中。
所以基本上在第一种情况下,T => Int所以out T => out Int => out Number也许。在第二种情况下,T => out Number任何是 Number 的子类,那么仍然out T => out Number正确吗?
我无法理解为什么它不能按这种逻辑工作......
MutableList 是一个函数参数。你会遇到完全相同的问题:
class Test11<T : Number> {
fun test(list: MutableList<out T>) {
}
}
fun main() {
val test: Test11<Number> = Test11<Number>()
val test2: Test11<out Number> = test
test.test(MutableList(3) { 55 }) // First
test2.test(MutableList(3) { 55 }) // Second
}
Run Code Online (Sandbox Code Playgroud)
根据定义,协变类型可防止调用类型为参数的函数,但这在逻辑上也扩展到相同类型的嵌套协变。如果 T 是协变的(对于类),那么消费一个可以产生 Ts 的对象并不比直接消费 Ts 更安全。
这将如何导致失败的示例:
class Test11<T : Number> {
var list: MutableList<out T>? = null
fun test(list: MutableList<out T>) {
this.list = list
}
}
fun main() {
val test: Test11<Long> = Test11()
val test2: Test11<out Number> = test
val doubleList: MutableList<out Number> = mutableListOf(1.0)
test2.test(doubleList) // Not allowed
// if it were allowed:
val long: Long? = test.list?.firstOrNull() // ClassCastException casting the Double to a Long
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |