Middle
Ako pracovať s generickými typmi v Kotlin?
sobes.tech AI
Odpoveď od AI
Generické typy v Kotlin umožňujú vytvárať triedy, rozhrania a funkcie, ktoré pracujú s dátami rôznych typov, pričom zachovávajú typovú bezpečnosť počas kompilácie.
Hlavné pojmy a spôsoby práce:
- Deklarácia generických tried a rozhraní:
class Box<T>(val item: T) // Generická trieda s parametrom typu T interface MyList<E> { // Generické rozhranie s parametrom typu E fun add(element: E) fun get(index: Int): E } - Deklarácia generických funkcií:
fun <T> printAnything(value: T) { // Generická funkcia s parametrom typu T println(value) } - Vytváranie inštancií generických typov:
val intBox: Box<Int> = Box(123) // Určenie konkrétneho typu (Int) val stringBox = Box("hello") // Kompilátor odvodí typ (String) - Variabilita: Umožňuje určiť, ako fungujú podtypy s generickými typmi.
- Kovariencia (out): Umožňuje používanie typu a jeho podtypov. Označuje sa
out. Príklad:List<out Any>môže obsahovaťList<String>. Používa sa pre typy, ktoré produkujú hodnoty (napríklad čítanie z kolekcie).interface Producer<out T> { // out T - kovariantný parameter fun produce(): T } - Kontravariancia (in): Umožňuje používanie typu a jeho nadtypov. Označuje sa
in. Príklad:Comparator<in String>môže pracovať sComparator<Any>. Používa sa pre typy, ktoré konzumujú hodnoty (napríklad zápis do kolekcie).interface Consumer<in T> { // in T - kontravariantný parameter fun consume(value: T) } - Invariancia: Typ v generickom parametri musí byť presne rovnaký. Toto je predvolené správanie.
- Kovariencia (out): Umožňuje používanie typu a jeho podtypov. Označuje sa
- Obmedzenia typov (
where): Umožňuje obmedziť typ parametra tak, aby implementoval určité rozhrania alebo dedil z určitej triedy.fun <T : Comparable<T>> max(a: T, b: T): T { // T musí implementovať Comparable return if (a > b) a else b } fun <T> process(item: T) where T : Runnable, T : Comparable<T> { item.run() // ... používame porovnateľnosť } - Hviezdička (star) projekcia (
*): Používa sa, keď nie sú dôležité konkrétne argumenty typu. Podobne ako<?>v Jave.fun printList(list: List<*>) { // Môže prijať zoznam akéhokoľvek typu for (item in list) { println(item) } }
Generické typy v Kotlinu používajú stratu typov (type erasure), rovnako ako v Jave. Informácie o konkrétnych typoch parametrov sa strácajú počas behu. Na prácu s typmi počas behu sa používajú reified typy.
- Reified typy (
reified): Dostupné sú iba pre inline funkcie. Umožňujú zachovať informácie o type parametra počas behu.inline fun <reified T> checkType(value: Any) { // T - reified typ if (value is T) { println("Value is of type T") } else { println("Value is not of type T") } }