泛型;类型参数不在其范围内

时间:2021-01-14 13:27:16

标签: kotlin generics

我最近一直在试验泛型,并找到了一个可以使用它们的好例子,但是,我陷入了困境,我的搜索没有找到解决方案,或者我误解了。请参阅以下代码示例:

open class X()
class Y : X()
class Z : X()

abstract class A<T : X> {
    lateinit var one: T

    fun setup(
        one: T
    ) {
        this.one = one
    }
}

class B<T : Y> : A<T>()

class C {

    fun initB() {
        B<Y>() // Works as intended
        B<Z>() // Type argument is not within its bounds
        B<X>() // Type argument is not within its bounds
    }

}

我想要一种情况,即从 one 类型的 class B 访问 one 是正确推断的,所以如果我实例化 B 类型为 Z那么 one 也将被推断为类型 Z。不幸的是,按照我认为正确的方式执行此操作会导致“Type argument is not within its bounds”。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

B 的类型必须是您定义的 Y 的子类型 B<T : Y>,但 X 和 Z 都不是 Y 的子类型。X 是 Y 的超类型,而 Z 与 Y 根本没有垂直联系.

即使它们是亚型,你也不能做你希望做的事。由于您的类有一个 T 变量,因此 T 必须保持不变才能工作。不变意味着您不能隐式地向上和向下转换类的实例的类型。

考虑一下如果它允许你它会如何崩溃:

val bY: B<Y> = B<Y>()
val bX: B<X> = bY // not allowed because of invariance

// If it were allowed:
bX.one = X()
val y: Y = bY.one // ClassCastException: cannot cast X to Y