类型参数中的交叉引用 [英] Cross references in type parameters

查看:96
本文介绍了类型参数中的交叉引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,在Java中,我可以写:

For example in Java I could write:

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

然后在某个地方扩展此类:

And then, somewhere, extend this classes:

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

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

But when I tried to implement same class hierarchy in 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

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中重现相同的类型参数限制吗?

Is there any way to reproduce same type parameter restrictions in Kotlin?

推荐答案

Kotlin没有原始类型,您不能只删除类型参数.

Kotlin doesn't have raw types, you cannot just drop the type parameters.

与原始类型相似的一个选项是使用星空投影:

One option similar to raw types is to use star projections:

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

但是您将无法正常使用类型参数的泛型成员.

But you won't be able to normally work with the type parameters generic members.

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

Another option is to introduce mutual constraints like this:

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>.

With this definition, you can be sure that if you define SomeSnapshot: Snapshot<SomeSnapshot, SomeElement>, the type SomeElement is aware of SomeSnapshot, because it is constrained to be derived from Element<SomeElement, SomeSnapshot>.

然后实现为:

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

这篇关于类型参数中的交叉引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆