Выбор ответа 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 число.
Варианты ответа
- В интерфейсе нельзя объявлять методы с параметрами
- Для параметра типа нужно добавить
reified - Метод
putдолжен бытьsuspend, иначе T не вывести Tсoutстоит в позиции параметра методаправильный ответ
Разбор
Если бы Producer<out T> мог принимать T, можно было бы взять Producer<String>, присвоить в Producer<Any> (разрешено ковариантностью) и передать в put число. Поэтому компилятор запрещает out-параметр в позиции параметра метода. Обход для безопасных случаев: @UnsafeVariance, так сделан contains(element: E) в List.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Дженерики и вариантность»
- Проверка is List<String> и стирание типов
- Вариантность в объявлении и в месте использования
- Как обойти стирание типов
- Инвариантность, out и in
- Контравариантность in T
- Конфликт перегрузок из-за стирания
- Почему List<String> можно передать как List<Any>
- Дженерики Kotlin и Java