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.