Kotlin的逆差异(Contravariance in Kotlin)
我从来没有真正理解Java中的泛型,所以Kotlin似乎就是这种情况。 考虑以下代码片段(这是一个人为的例子):
class AnyComparator: Comparator<Any> { override fun compare(o1: Any, o2: Any): Int { TODO("not implemented") } } fun <T> test() { val x: Comparator<in Double> = AnyComparator() // OK! val y: Comparator<in T> = AnyComparator() // Compilation error }
第二个赋值因错误而失败
Type mismatch. Required: kotlin.Comparator<in T> Found: AnyComparator
现在,如果我理解正确的
in
修饰符表明T
只被泛型类型Comparator
(它产生逆变),那么我应该能够为任何Comparator
分配类型参数E
,它是T
的基类。 基于此,我应该能够将AnyComparator
分配给变量x
和y
,因为Any
类型是Kotlin中每个类的基类。 事实证明我不能,我不明白为什么。I never truly understood generics in Java, so it seems to be the case with Kotlin. Consider the following code snippet (it's a contrived example):
class AnyComparator: Comparator<Any> { override fun compare(o1: Any, o2: Any): Int { TODO("not implemented") } } fun <T> test() { val x: Comparator<in Double> = AnyComparator() // OK! val y: Comparator<in T> = AnyComparator() // Compilation error }
The second assignment fails with the error
Type mismatch. Required: kotlin.Comparator<in T> Found: AnyComparator
Now, if I understand correctly the
in
modifier indicates theT
is only consumed by the generic typeComparator
(it makes contravariant), so I should be able to assign anyComparator
with type argumentE
which is the base class ofT
. Based on this, I should be able to assignAnyComparator
to both variablesx
andy
, since the typeAny
is the base class of every class in Kotlin. It turns out I can't, and I don't understand why.
原文:https://stackoverflow.com/questions/44861928
最满意答案
它可能看起来很奇怪,但
Any
不是所有kotlin类的超类,而只是不可为空的类。 所有Kotlin课程的真正超类是Any?
(它也是Any
的超类)。
test
函数中的泛型类型T
没有上限,因此它可以是一个可为空的对象Any?
。 错误是因为当您需要Comparator<Any?>
时,您不能使用Comparator<Any>
Comparator<Any?>
。因此,您可以修复将
T
上限定义为Any
示例:fun <T: Any> test() { //... }
It can be seem strange but
Any
is not the superclass of all kotlin classes but only of not nullable classes. The real superclass of all Kotlin classes isAny?
(it is also a superclass ofAny
).The generic type
T
in yourtest
function has no upper bound so it can be a nullable objectAny?
. The error is because you can't aComparator<Any>
when you need aComparator<Any?>
.So you can fix your example defining the
T
upper bound asAny
:fun <T: Any> test() { //... }