如何解决Kotlin有限束缚的侵犯?

假设我在Java中有这个声明,没关系。

abstract class Start<T extends End> { public T end; } abstract class End<T extends Start> { public T start; } 

然而,在Kotlin中这并不好,因为Kotlin对“循环”类型参数有限制。

 abstract class Start<T : End<*>> { lateinit var end: T } abstract class End<T : Start<*>> { lateinit var start: T } 

在Kotlin中有没有解决这个问题的方法,以便我可以有相互依赖的泛型类型?

仅使用一个类型参数是不可能的。 Self介绍类型,这是本地支持的一些其他语言,是必要的。 但是,在kotlin中,您必须Self介绍Self类型,因为JetBrains正式拒绝了添加自我类型的请求 。

 abstract class Start<Self: Start<Self, T>, T: End<T, Self>> { lateinit var end: T } abstract class End<Self: End<Self, T>, T: Start<T, Self>> { lateinit var start: T } 

PS:这个Self可能会在后来引起冗长的类型。 谨慎行事。

设G是一个有向图,其顶点是程序中所有泛型类型声明的所有类型参数。 对于G中每个类型的参数T的B闭包中的每种类型的每个类型的组合类型中的每个泛型类型B <…>中的每个投影类型参数A, T到U,其中U是与类型参数A相对应的B <…>声明的类型参数。如果图G具有一个循环,那么这是一个编译时错误。

注意:图G中边X→Y的直观含义是“类型参数X的边界的确切含义取决于类型参数Y的边界”。

例:

下面的声明是无效的,因为有一个边T→T,形成一个循环:

 interface A<T : A<*>> 

边界A < >是一个带有隐式边界的投影。 如果该边界是明确的,则类型A < >采用等同形式A >>。 以同样的方式,它可以进一步改写成与A >>>等价。 在完全展开的形式下,这个界限将是无限的。 这个规则的目的是为了避免这种无限的类型,以及类型检查相关的困难。

下面的一对声明是无效的,因为存在边T→S和S→T,形成一个循环:

 interface B<T : C<*>> interface C<S : B<*>> 

下面的声明是无效的,因为存在边K→V和V→K,形成一个循环:

 interface D<K: D<K, *>, V: D<*, V>> 

另一方面,以下每个声明都是有效的:

 interface A<T : A<T>> interface D<K, V : D<*, V>> 

TODO:这些算法与灵活类型的交互。 TODO:在Java中声明的违反这些规则的导入类型。

子类型关系是由归纳决定的,即必须有一个有限的证明。

 interface N<in T> interface A<S> : N<N<A<A<S>>>> 

官方链接