Общее свойство класса Kotlin

Я знаю, что это может показаться повторяющимся вопросом, но я озадачен тем, как работают инвариантность, ковариантность и контравариантность.

Я не могу понять, почему я не могу скомпилировать этот фрагмент:

class Test<X: List<Any>>{
    lateinit var list2:List<Any>
    lateinit var list1:X

    fun putList(){
        list2 = emptyList()
        list1 = emptyList<Any>()
    }
}

Я получаю сообщение об ошибке несоответствия типа Required X found List

Однако, если я определю общий X как «out», я получу ошибку, указывающую, что параметр X является инвариантным в list1 var.

Может ли кто-нибудь помочь еще одной бедной душе, заблудившейся в дженериках Kotlin?


person Joao Neto    schedule 28.03.2018    source источник


Ответы (1)


Краткий ответ: переменная list1 является ковариантной, вы пытаетесь использовать ее контравариантным образом.

Что вы сейчас пытаетесь сделать: присвойте экземпляр супертипа (указанного верхней границей) List<Any> переменной его подтипа X, то есть list1. Для упрощения задачи рассмотрим следующее:

open class Super
class Sub : Super()
val sub: Sub = Super() //Compile Error: Type mismatch: inferred type is Super but Sub was expected

Вы просто не можете назначать объекты переменным подтипа этого объекта. А вот наоборот было бы нормально val sup: Super = Sub()

person s1m0nw1    schedule 28.03.2018
comment
Ага. Я предполагал, что List будет подтипом самого себя, и я мог бы назначать подтипы, такие как MutableList и сам... Спасибо! - person Joao Neto; 28.03.2018