Что делает in / out в kotlin, когда передается в качестве аргумента? - PullRequest
0 голосов
/ 14 апреля 2019

Я просмотрел kotlin документы, блоги и сообщения stackoverflow, чтобы понять, в и в в kotlin .Как я обнаружил, теория здесь такова: Потребитель в (принимает), Производитель в (возвращает).

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

private fun exampleMethod1(list: ArrayList<out String>) {

}

private fun exampleMethod2(list: ArrayList<in String>) {

}

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Позвольте мне продемонстрировать, что происходит с помощью примера. Учтите следующее:

private fun foo(list: ArrayList<Number>) {}

private fun bar(list: ArrayList<Number>) {}

Теперь мы попытаемся передать ArrayList каждой функции, каждая с различным параметром универсального типа:

// Error: Type Mismatch. Required `ArrayList<Number>` Found `ArrayList<Int>`
foo(arrayListOf<Int>())

// Error: Type Mismatch. Required `ArrayList<Number>` Found `ArrayList<Any>`
bar(arrayListOf<Any>())

Но мы получаем ошибки! Как мы решаем это? Мы должны как-то сообщить компилятору, что для foo список также может содержать элементы подтипа Number (например, Int), а для bar мы должны сообщить компилятору, что список также может содержать элементы базового типа Number (например, Any).

private fun foo(list: ArrayList<out Number>) {}

private fun bar(list: ArrayList<in Number>) {}

И теперь это работает!

Дополнительная литература

0 голосов
/ 14 апреля 2019

Речь идет о ковариантности и контравариантности. Когда вы говорите, что ваша функция принимает List<out T>, это означает, что она может принимать List<T> или любой список, типизированный классом, унаследованный от T. С другой стороны, функция с List<in T> может принимать List<T> и любой список, набранный T суперклассом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...