Kotlin
Дженерики
Поиск…
Вступление
Список может содержать числа, слова или действительно что угодно. Вот почему мы называем общий список.
Генерики обычно используются для определения типов, которые может содержать класс, и типа, который в данный момент хранит объект.
Синтаксис
- class ClassName < TypeName >
- class ClassName <*>
- ClassName <in UpperBound >
- ClassName <out LowerBound >
- class Name < TypeName : UpperBound >
параметры
| параметр | подробности |
|---|---|
| TypeName | Тип Имя общего параметра |
| Верхняя граница | Ковариантный тип |
| Нижняя граница | Контравариантный тип |
| ИмяКласса | Название класса |
замечания
Подразумеваемая верхняя граница - Nullable
В Kotlin Generics верхняя граница параметра типа T будет Any? , Поэтому для этого класса:
class Consumer<T>
Параметр типа T действительно T: Any? , Чтобы сделать верхнюю границу с недействительными значениями, явно определенную T: Any . Например:
class Consumer<T: Any>
Отклонение на сайте
Отклонение на уровне объявления можно рассматривать как объявление разницы в использовании сайта один раз и на всех сайтах-участницах.
class Consumer<in T> { fun consume(t: T) { ... } }
fun charSequencesConsumer() : Consumer<CharSequence>() = ...
val stringConsumer : Consumer<String> = charSequenceConsumer() // OK since in-projection
val anyConsumer : Consumer<Any> = charSequenceConsumer() // Error, Any cannot be passed
val outConsumer : Consumer<out CharSequence> = ... // Error, T is `in`-parameter
Широко распространенными примерами дисперсии объявления-сайта являются List<out T> , который является неизменным, поэтому T появляется только как тип возвращаемого значения и Comparator<in T> , который принимает только T как аргумент.
Распределение на месте
Разница между сайтом и сайтом похожа на маскировку Java:
Из-проекции:
val takeList : MutableList<out SomeType> = ... // Java: List<? extends SomeType>
val takenValue : SomeType = takeList[0] // OK, since upper bound is SomeType
takeList.add(takenValue) // Error, lower bound for generic is not specified
В-проекции:
val putList : MutableList<in SomeType> = ... // Java: List<? super SomeType>
val valueToPut : SomeType = ...
putList.add(valueToPut) // OK, since lower bound is SomeType
putList[0] // This expression has type Any, since no upper bound is specified
Звезда-проекции
val starList : MutableList<*> = ... // Java: List<?>
starList[0] // This expression has type Any, since no upper bound is specified
starList.add(someValue) // Error, lower bound for generic is not specified
Смотрите также:
Возможность взаимодействия разновидностей Generic при вызове Kotlin с Java.