考虑以下设置:
open class Base
open class Derived: Base()
interface Foo<T: Base> {
fun produce(): T
fun consume(aT: T)
}
以下功能有效:
fun apply1(f: Foo<*>) {
val p: Base = f.produce();
}
fun apply2(f: Foo<Derived>) {
val p: Base = f.produce();
}
但这不是:
fun apply3(f: Foo<in Derived>) {
val p: Base = f.produce();
}
Type mismatch
Required: Base
Found: Any?
通用类型参数
T
具有上限。因此可以安全地将其视为Base
的子类型,因为它是在apply1
和apply2
中完成的。问题是,为什么用in
投影时做同样的事情无效?
最佳答案
这些关键字是为限制而设计的,您可以在希望确保用户不会从该对象读取和写入值时指定它。
它试图避免的缺陷在Kotlin official documentation(方差+类型投影)中进行了解释。
in关键字仅允许带注释的目标使用,而out关键字用于产生值。您的apply3函数应使用out关键字来指定目标是仅从foo参数生成值。
相反,在某些地方有一个限制,用于指定您要让Foo对象消费,仅此而已。
关于generics - 为什么在具有上限的投影泛型类型中,生产者方法的返回类型为Any?而不是上限类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61231708/