Каковы правила использования ключевого слова out в дженериках без получения ошибки компиляции?

В Котлине я изучаю ковариант (подтип можно использовать вместо супертипа). Написали там что-то вроде правила. но мне кажется это неправильным. Это написано:

Однако вы не можете использовать out, если у класса есть параметры функции или свойства var этого универсального типа.

Но я думаю, что слово или следует заменить словом и, потому что в ситуации, когда в классе есть функция, которая получает тип в качестве параметра, если свойство общий тип — это val, а не var, и ущерб не может быть причинен, поскольку любое присвоение свойству val невозможно. Я прав или то, что написано в книге правильно, и я что-то упускаю?

Редактировать: я только что понял (согласно некоторому сообщению, которое я видел на этом форуме), что единственная ситуация, когда параметр может быть проблемой, хотя свойство объявлено как val, в случае, если у нас есть контейнер типа T, скажем, список, тогда может возникнуть проблема, если мы попытаемся добавить в список, но если у нас нет контейнера, я не вижу ситуации, когда получение типа параметра может вызвать проблемы в то время как свойство val. Я прав?


person Eitanos30    schedule 14.11.2020    source источник


Ответы (1)


Ключевое слово out используется для ковариации, а не для контравариантности.

Вот простой пример проблемы, возникающей в воображаемом классе, где разрешена ковариация для типа свойства var:

class Container<out T>(var item: T)

val intContainer = Container<Int>(1)
val numberContainer: Container<Number> = intContainer // cast is allowed for covariant type
numberContainer.item = 5f // allowed if item is a var
val intValue = intContainer.item // Float value is cast to an Int!

Это невозможно с val, поэтому приведенный выше класс мог бы быть ковариантным на сайте объявления, если бы item был val.

person Tenfour04    schedule 14.11.2020
comment
спасибо, но мне не удалось найти пример, в котором может возникнуть проблема, если методы получают тип параметра в качестве аргумента, если тип параметра служит свойством val в классе Container. - person Eitanos30; 15.11.2020