Свойство родового класса Kotlin

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

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

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

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

Я получаю ошибку несоответствия типов Обязательный X найден Список

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

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

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()

Другие вопросы по тегам