I'm new to Kotlin. When trying to convert a java application to Kotlin I ran into the following issue so posting this question.
This is a model-view-binder app and here are the java interfaces. Key thing is Model and View are interdependent on each other.
interface Model<T extends View<?>> {}
interface View<T extends Model<?>> {}
class RealModel implements Model<RealView> {}
class RealView implements View<RealModel> {}
class Binder<T extends Model<?>> {
static <ModelT extends Model<?>> Binder<ModelT> of(View<ModelT> view) {}
}
// Application code
Binder<RealModel> binder = Binder.of(new RealView());
binder.bind(new RealModel());
Can I do this in Kotlin?
I tried the following
interface Model<T : View<*>> {}
ERROR: This type parameter violates the Finite Bound Restriction
interface Model<T : View<Any>> {}
ERROR: Type argument is not within its bounds: should be subtype of 'Model<*>'
interface Model<T : View<Model<*>>> {}
ERROR: This type parameter violates the Finite Bound Restriction
You can't convert it 1:1 in Kotlin since Kotlin restricts the cyclic type parameters.
You can solve it adding a new type parameter which other languages supports natively but Kotlin doesn't, which is the self
type parameter (identified with S
in my example) and making the self
type parameter and the other type parameter as covariant types (using out
):
interface Model<out S : Model<S, T>, out T : View<T, S>>
interface View<out S : View<S, T>, out T : Model<T, S>>
class RealModel : Model<RealModel, RealView>
class RealView : View<RealView, RealModel>
class Binder<T : Model<*, *>> {
companion object {
fun <ViewT : View<*, ModelT>, ModelT : Model<ViewT, *>> of(view: ViewT): Binder<ModelT> {
throw RuntimeException()
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.