简体   繁体   中英

Interfering type parameter based on another type parameter

Is it possible to Kotlin Compiler to infer type parameter based on another type parameter? That is: infere type A based on type B in IntExample class definition.

interface Something<A>

interface Example<A, B: Something<A>>

class IntSomething: Something<Int>

// Can Int type parameter be infered by the fact that IntSomething is Something<Int>?
// If yes, how could I specify B type parameter without specifing the infered A (Int) parameter?
class IntExample: Example<Int, IntSomething> // specifing Int here is painful!!!

Imagine that we have more type parameters like that - it will be a lot of boilerplate to specify each of them if some might (theoretically) be infered.

The question is: What are you doing with type parameters A and B ?

If you do not need parameter A , you can just omit it and instead write:

interface Example<B: Something<*>>

Then B can be any subtype of Something and you do not need to specify it. If you need to know what A is, you need to specify it. Note that the type parameter A on Something<A> does not exist at runtime, so you cannot just ask an instance of B what its Something -type parameter is. And Kotlin cannot do that either, because the information is just not there, if it is not explicitly specified by you.

But maybe it is easier to get rid of type parameter B . Is it important for you that you have a specific subtype of Something<A> ? If it is not important, you could just omit type parameter B and always use Something<A> instead inside your Example class.

If it is important, Kotlin cannot possibly know by itself which specific implementation of Something<A> you want to use. There could always be several subclasses, for instance:

class IntSomething: Something<Int>
class IntSomething2: Something<Int>

Here I have two subclasses of Something<Int> . Which one is the right one?

But maybe it could be infered not for a class, but for a function, like so:

interface Example<A> {
    fun <B: Something<A>> doSomething(b: B): B
}

class IntExample : Example<Int> {
    override fun <B: Something<Int>> doSomething(b: B): B {
        // do something with right type based on b
        return b
    }
}

Doing it this way, Kotlin can infer the right implementation of Something<A> based on your parameter at runtime:

val example = IntExample()
val x = example.doSomething(IntSomething()) // x has type IntSomething
val y = example.doSomething(IntSomething2()) // y has type IntSomething2

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM