Middle
Как да работите с обобщени типове в Kotlin?
sobes.tech AI
Отговор от AI
Обобщените типове в Kotlin позволяват създаването на класове, интерфейси и функции, които работят с данни от различни типове, като същевременно запазват типобезопасността по време на компилация.
Основни понятия и начини на работа:
- Деклариране на обобщени класове и интерфейси:
class Box<T>(val item: T) // Обобщен клас с параметър тип T interface MyList<E> { // Обобщен интерфейс с параметър тип E fun add(element: E) fun get(index: Int): E } - Деклариране на обобщени функции:
fun <T> printAnything(value: T) { // Обобщена функция с параметър тип T println(value) } - Създаване на екземпляри на обобщени типове:
val intBox: Box<Int> = Box(123) // Посочване на конкретен тип (Int) val stringBox = Box("hello") // Компилаторът извежда типа (String) - Вариантност: Позволява определяне как работят подтиповете с обобщените типове.
- Ковариантност (out): Позволява използването на типа и неговите подтипове. Обозначава се с
out. Пример:List<out Any>може да съдържаList<String>. Използва се за типове, които произвеждат стойности (например четене от колекция).interface Producer<out T> { // out T - ковариантен параметър fun produce(): T } - Контравариантност (in): Позволява използването на типа и неговите надтипове. Обозначава се с
in. Пример:Comparator<in String>може да работи сComparator<Any>. Използва се за типове, които консумират стойности (например запис в колекция).interface Consumer<in T> { // in T - контравариантен параметър fun consume(value: T) } - Инвариантност: Типът в обобщения параметър трябва да бъде точно същият. Това е поведението по подразбиране.
- Ковариантност (out): Позволява използването на типа и неговите подтипове. Обозначава се с
- Ограничения на типове (
where): Позволява да ограничите типа параметър, така че той да реализира определени интерфейси или да наследява от определен клас.fun <T : Comparable<T>> max(a: T, b: T): T { // T трябва да реализира Comparable return if (a > b) a else b } fun <T> process(item: T) where T : Runnable, T : Comparable<T> { item.run() // ... използване на сравнимост } - Звездна (star) проекция (
*): Използва се, когато не е важно конкретното аргументно тип. Аналогично на<?>в Java.fun printList(list: List<*>) { // Може да приема списък от всеки тип for (item in list) { println(item) } }
Обобщените типове в Kotlin използват изтриване на типове (type erasure), както и в Java. Информацията за конкретните типове параметри се губи по време на изпълнение. За работа с типове по време на изпълнение се използват reified типове.
- Reified типове (
reified): Достъпни са само за inline функции. Позволяват запазване на информация за типа на параметъра по време на изпълнение.inline fun <reified T> checkType(value: Any) { // T - reified тип if (value is T) { println("Value is of type T") } else { println("Value is not of type T") } }