Hello Kotliners, I face a problem with type erasure, is there a way to implements implementation of same generic interface with different types ?
fun main() {
val foo = Foo()
println(foo[0])
println(foo[0L])
}
interface Index<Idx, Type> {
operator fun get(i: Idx): Type
}
interface IntIndex<Type> {
operator fun get(i: Int): Type
}
interface LongIndex<Type> {
operator fun get(i: Long): Type
}
// class Foo: Index<Int, String>, Index<Long, String> <- This is forbidden
class Foo: IntIndex<String>, LongIndex<String> { // This is allowed
override fun get(i: Int) = "TODO for Int"
override fun get(i: Long) = "TODO for Long"
}
Sounds like a JVM restriction – both Index<Int, String>
and Index<Long, String>
represent the same nominal type. So a supertype declaration can only contain one of them; Whereas IntIndex
and LongIndex
are treated as different nominal types.
1 Like
Thanks for the response . Anyone knows if the Valhalla project will “fix” this problem ?
No, it won’t. Valhalla has nothing to do with generics. Actually, in Kotlin you can work around type erasure if you are using compile-time dispatch. Like this:
fun doSomething(list: List<Double>){}
@JvmName("doSomethingWithList")
fun doSomething(list: List<Int>){}
fun main(){
doSomething(listOf(1,2,3))
}
Correction. Part of Valhalla IS about generics, especially reified generics for value-types. But it is not about type erasure.
Yes that’s why I believe that it would be possible to implements two types in Kotlin as the compiler can perform non valid Java dispatch. By the way thanks for the response