Я не могу понять, и я не смог найти значение ключевого слова out в kotlin.
Здесь вы можете проверить пример:
List<out T>
Если кто-то может объяснить смысл этого. Было бы очень благодарно.
Я не могу понять, и я не смог найти значение ключевого слова out в kotlin.
Здесь вы можете проверить пример:
List<out T>
Если кто-то может объяснить смысл этого. Было бы очень благодарно.
С этой сигнатурой:
List<out T>
вы можете сделать это:
val doubleList: List<Double> = listOf(1.0, 2.0)
val numberList: List<Number> = doubleList
что означает T ковариантный:
когда объявлен параметр типа T класса C out, C <Base> можно безопасно быть супертипом C <Derived> .
Это контрастирует с в, например.
Comparable<in T>
вы можете сделать это:
fun foo(numberComparable: Comparable<Number>) {
val doubleComparable: Comparable<Double> = numberComparable
// ...
}
что означает T контравариантный:
когда параметр T класса C объявлен в, C <Derived> может безопасно быть супертипом C <Base> .
Еще один способ запомнить это:
Потребитель в, производитель вне.
Обратитесь к инструкции руководства по kotlin
Тип Kotlin
List<out T>
- это интерфейс, который предоставляет только чтение такие операции, как размер, получение и т.д. Как и в Java, он наследуетCollection<T>
и который, в свою очередь, наследует отIterable<T>
. Методы, которые изменение списка добавляется интерфейсомMutableList<T>
. Эта шаблон имеет место также дляSet<out T>/MutableSet<T>
иMap<K, out
V>/MutableMap<K, V>
И это,
В Котлине есть способ объяснить подобные вещи компилятор. Это называется дисперсией объявления-сайта: мы можем аннотировать параметр типа T источника, чтобы убедиться, что он возвращается только (производится) от членов
Source<T>
и никогда не потребляется. Сделать это мы предоставляем модификатор out:> abstract class Source<out T> { > abstract fun nextT(): T } > > fun demo(strs: Source<String>) { > val objects: Source<Any> = strs // This is OK, since T is an out-parameter > // ... }
Общее правило: когда объявлен параметр типа
T
классаC
это может произойти только в позиции внеC
, но в returnC<Base>
может безопасно быть супертипомC<Derived>
.В "умных словах" говорят, что класс
C
ковариантен в параметрT
или чтоT
является параметром ковариантного типа. Вы можете думать о C как производитель T, и НЕ потребительT
. Модификатор out называется аннотацией дисперсии, и поскольку он приведенные на сайте объявления параметров типа, мы говорим о дисперсия объявления-сайта. Это контрастирует с Java-сайтом дисперсия, где подстановочные знаки в типах использования делают типы ковариантными.
List<out T> is like List<? super T> in Java
и
List<in T> is like List<? implements T> in Java
Например, в Котлине вы можете делать такие вещи, как
val value : List<Any> = listOf(1,2,3)
//since List signature is List<out T> in Kotlin