Ковариация в коллекциях Kotlin - PullRequest
0 голосов
/ 22 марта 2020

Я в основном хотел спросить о двух указанных c типах - MutableList и Array.

Почему это нормально:

var anyList: List<Any> = mutableListOf<String>("1", "2") //why is MutableList covariant?
var intList: List<Int> = mutableListOf<Int>(1, 2)
anyList = intList //Why is this Ok? Where's covariance in the corresponding declaration sites?

Почему MutableList позволяет ковариация в своем типе? Исходя из его объявления, в нем нет модификатора out:

public interface MutableList<E> : List<E>, MutableCollection<E>

В то же время для Array он отличается:

var anyArray: Array<Any> = arrayOf("1", "2") //why is this is fine if arrayOf returns invariant Array<T>
    var intArray: Array<Int> = arrayOf(1, 2)
    anyArray  = intArray //but this is not(compilation error)

1 Ответ

1 голос
/ 22 марта 2020

Ах, нашел ответ на свой вопрос:

Хитрость в том, что MutableList наследует обычный список:

public interface MutableList<E> : List<E>, MutableCollection<E>

И интерфейс обычного списка ковариантен в E:

public interface List<out E> : Collection<E>

Итак, если я изменю свой исходный код на:

var anyList: MutableList<Any> = mutableListOf<String>("123") //doesn't compile any longer
var intList: MutableList<Int> = mutableListOf<Int>(1)
anyList = intList //won't work either

ОБНОВЛЕНИЕ

Как указано в комментарии

С Array это совсем другое. Это работает, потому что я не пытался явно определить тип в правой части инструкции, и поэтому Array<Any> выводится независимо от значений, которые я передал в качестве параметров arrayOf()

public inline fun <reified @PureReifiable T> arrayOf(vararg elements: T): Array<T>
...