这是我很难理解为什么第一次编译而第二次不编译的代码?
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
}
第二个说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
}
根据定义,协变类型可以防止调用以类型为参数的函数,但是从逻辑上讲,这也扩展到相同类型的嵌套协变。如果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
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句