Выбор ответа Senior Дженерики и вариантность обновлено

Почему out T нельзя в параметре

Вопрос

Почему этот код не компилируется?

interface Producer<out T> {
    fun get(): T
    fun put(item: T)
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: T с out стоит в позиции параметра метода. Если бы Producer<out T мог принимать T, можно было бы взять Producer<String, присвоить в Producer<Any (разрешено ковариантностью) и передать в put число.

Варианты ответа

  1. В интерфейсе нельзя объявлять методы с параметрами
  2. Для параметра типа нужно добавить reified
  3. Метод put должен быть suspend, иначе T не вывести
  4. T с out стоит в позиции параметра методаправильный ответ

Разбор

Если бы Producer<out T> мог принимать T, можно было бы взять Producer<String>, присвоить в Producer<Any> (разрешено ковариантностью) и передать в put число. Поэтому компилятор запрещает out-параметр в позиции параметра метода. Обход для безопасных случаев: @UnsafeVariance, так сделан contains(element: E) в List.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.