open class A
class B: A()
fun <T> copy(src: MutableList<T>, dst: MutableList<T>) {
for (i in 0 until src.size) {
dst.add(i, src[i])
}
}
Я понимаю, что для вышеупомянутого кода copy function
ожидает, что оба параметра типа будут точно такого же типа. С небольшой модификацией copy(src: MutableList<T>, dst: MutableList<in T>)
обратите внимание на ключевое слово in, я говорю, что src
должен быть точного типа T
, но назначение может быть type T
или любого супертипа T .
Для приведенного выше модифицированного кода я могу вызвать метод следующим образом:
fun main(args: Array<String>) {
val l1 = mutableListOf(B(), B())
val l2 = mutableListOf<A>()
copy(l1, l2)
} // main
Приведенный выше copy(l1, l2)
не работает, если я удаляю in
из места назначения (понятно).
Мой вопрос в том, что я могу вызвать функцию без каких-либо ошибок, если обновить параметр функции src
, чтобы принять out
проекцию списка. например
fun <T> copy(src: MutableList<out /*notice out here*/ T>, dst: MutableList<T>) {
for (i in 0 until src.size) {
dst.add(i, src[i])
}
}
В данном случае я не могу понять, что происходит под капотом. Кто-нибудь может объяснить, пожалуйста?
Обратите внимание, что это всего лишь пример из книги. Я знаю, что могу использовать List
вместо неизменяемого списка в src