Hi guys. I’m studying kotlin and I’m on type proje...
# kotlin-in-action
r
Hi guys. I’m studying kotlin and I’m on type projection section. What I miss?
Copy code
open class Noun(val n: String)
open class City(val c: String) : Noun(c)
open class Cabrobro(val j: String) : City(j)

fun <T> copyData(source: MutableList<T>, destination: MutableList<in T>) {
    for (item in source) {
        destination.add(item)
    }
}

fun main(args: Array<String>) {
    val source= mutableListOf(City("c1"), City("c2"), City("c3"))
    val destination= mutableListOf<Cabrobro>()
    copyData(source, destination)
}
Why the compiler are not accepting
MutableList<Cabrobro>
as destination?
b
This seems to be a LSP issue. All
Cabrobro
instances are also
City
, but not all
City
instances are
Cabrobro
. So there’s not really a way to convert
City
into all potential sub types implicitly. Trying to do the inverse and qualifying a second generic type as a subtype of the first would work instead
Copy code
fun <T, R : T> copyData(source: List<R>, destination: MutableList<T>) {
    for (item in source) {
        destination.add(item)
    }

    // can also be written as just:
    // source.map(destination::add)
}
👍 1
This is also a great use case for an extension function
Copy code
fun <T, R : T> List<R>.copyTo(destination: MutableList<T>): MutableList<T> {
    this.map(destination::add)
    return destination
}

//inside main
val destination = source.copyTo(mutableListOf<City>())
👍 1
r
Thanks @bdawg.io