Cross references in type parameters

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 these classes:

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

But when I tried to implement the same class hierarchy in Kotlin:

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

I got the following compilation errors:

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

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

+4
source share
1 answer

Kotlin does not have source types; you cannot just discard type parameters.

One option, similar to the original types, is to use stellar forecasts :

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

But you will not be able to work normally with typical elements of typical parameters.


Another option is to introduce mutual restrictions, such as:

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>() { /* ... */ }
+10

Source: https://habr.com/ru/post/1676382/


All Articles