类型参数中的交叉引用

例如在Java中我可以写:

public abstract class Element<S extends Snapshot> { ... } public abstract class Snapshot<E extends Element> { ... } 

然后,在某个地方扩展这个类:

 public class SnapshotImpl extends Snapshot<ElementImpl> { ... } public class ElementImpl extends Element<SnapshotImpl> { ... } 

但是当我试图在Kotlin中实现相同的类层次时:

 abstract class Element<S : Snapshot> abstract class Snapshot<E : Element> 

我有以下的编译错误:

Error:(6, 28) Kotlin: One type argument expected for class Snapshot<E> defined in model Error:(6, 25) Kotlin: One type argument expected for class Element<S> defined in model

有什么办法可以在Kotlin中重现相同类型的参数限制吗?

Kotlin没有原始类型,你不能只删除类型参数。

类似于原始类型的一个选项是使用星形投影 :

 abstract class Element<S : Snapshot<*>> { /* ... */ } abstract class Snapshot<E : Element<*>> { /* ... */ } 

但是,您将无法正常使用类型参数通用成员。


另一个选择是引入这样的相互约束:

 abstract class Element<E : Element<E, S>, S : Snapshot<S, E>>() { /* ... */ } abstract class Snapshot<S : Snapshot<S, E>, E : Element<E, S>>() { /* ... */ } 

通过这个定义,您可以确定,如果定义了SomeSnapshot: Snapshot<SomeSnapshot, SomeElement> ,则SomeElement类型会知道 SomeSnapshot ,因为它受限于从Element<SomeElement, SomeSnapshot>派生。

那么执行将是:

 class SomeElement : Element<SomeElement, SomeSnapshot>() { /* ... */ } class SomeSnapshot : Snapshot<SomeSnapshot, SomeElement>() { /* ... */ }