Понимание одного использования ключевого слова "in" в Kotlin - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь понять, как Kotlin использует дженерики, особенно с ключевыми словами in и out.Я написал эти простые кусочки, чтобы, надеюсь, проиллюстрировать мою путаницу.

Этот метод выглядит и работает нормально;

enter image description here

Здесь IDE дает подсказку о том, что тип элемента, для которого выполняется цикл for, - это Shape.Это хорошо.

Еще одна версия описанного выше метода, которая на первый взгляд кажется не совсем правильной (поскольку это «потребитель»).Но все, что я хочу сделать, это прочитать список форм, и это все, что в этом «от».

enter image description here

Это не работает, чтоВозможно, это правильно в соответствии с правилами, но я не могу соединить точки здесь.Это похоже на безопасную операцию.Я также вижу, как Котлин вводит тип "Любой?"что объясняет, почему это уже дает ошибку компилятора.Может кто-нибудь объяснить потенциальную безопасность типа здесь, пожалуйста?

1 Ответ

0 голосов
/ 26 февраля 2019

Дисперсия - это всегда сложная концепция для проработки ...

Если вы используете термины «производитель» и «потребитель», учтите, что они относятся к вашему взаимодействию с рассматриваемым элементом ‚в данном случаепараметр MutableList.

Ваша первая функция с параметром MutableList<out Shape> может принимать список Shape s или список любого подкласса Shape.(out означает примерно «или любой подкласс».)

В каждом случае, если вы используете список, все, что вы извлекаете из списка, всегда будет Shape (как подтверждает IDE).).

Но если вы хотите поместить что-то в список (как производитель), вы не можете сказать, что было бы безопасно добавить, поскольку это зависело бы от того, является ли этои какой подкласс.

Ваша вторая функция с параметром MutableList<in Shape> противоположна: она может принимать список Shape с или список любого суперкласса Shape.(in означает примерно «или любой суперкласс».)

В каждом случае всегда безопасно добавить Shape в список (как производитель).Но вы ничего не можете сказать о типе того, что вы вытаскиваете из этого (как потребитель): его можно вызвать с MutableList<Any?>, который может содержать String s или Fileс или что угодно.Таким образом, компилятор присвоит ему универсальный тип Any? (как подтверждает IDE).

...