I’m struggling understanding how to use in/out for...
# announcements
j
I’m struggling understanding how to use in/out for generic types, here is what I’m trying to do :
Copy code
interface Executor<T, U> {
    fun isExecutable(): (T) -> Boolean
    fun execute(): suspend (U) -> Unit
}

class MyClass<T, U> {

     val executors = mutableMapOf<String, Executor<T, U>>()

    fun register(eventName: String, executor: Executor<T, U>) {
        executors[eventName] = executor
    }

    inline fun <reified V : U> register(executor: Executor<T, V>) {
        val eventName = V::class.toString()
        register(eventName, executor)
    }
}
I get the following error from the IDE
Type mismatch. Required: Executor<T, U>, Found: Executor<T, V>
U
is a sealed class and
V
a subtype of that class. I did read the page about generic and “PECS” in the doc, but I still haven’t figured it out. Anyone knows what I need to change?
e
your design isn't type safe and there's no way to express it in Kotlin without unchecked casts
Copy code
object A : Executor<Any?, Int> {
    override fun isExecutable() = { true }
    override fun execute() = suspend {
        assert(it is Int)
    }
}
val obj = MyClass<Any?, Any?>()
obj.register(A) // you want this function?
obj.executors.values.first().execute()("string") // this is allowed by the interface but cannot work
m
You can mark type parameters T and U as
in
but not
out