Middle
Jak pracovat s generickými typy v Kotlinu?
sobes.tech AI
Odpověď od AI
Generické typy v Kotlinu umožňují vytvářet třídy, rozhraní a funkce, které pracují s daty různých typů, přičemž zachovávají typovou bezpečnost během kompilace.
Hlavní pojmy a způsoby práce:
- Deklarace generických tříd a rozhraní:
class Box<T>(val item: T) // Generická třída s parametrem typu T interface MyList<E> { // Generické rozhraní s parametrem typu E fun add(element: E) fun get(index: Int): E } - Deklarace generických funkcí:
fun <T> printAnything(value: T) { // Generická funkce s parametrem typu T println(value) } - Vytváření instancí generických typů:
val intBox: Box<Int> = Box(123) // Určení konkrétního typu (Int) val stringBox = Box("hello") // Kompilátor odvodí typ (String) - Variabilita: Umožňuje určit, jak fungují podtypy s generickými typy.
- Kovarience (out): Umožňuje používat typ a jeho podtypy. Označuje se
out. Příklad:List<out Any>může obsahovatList<String>. Používá se pro typy, které produkují hodnoty (například čtení z kolekce).interface Producer<out T> { // out T - kovariantní parametr fun produce(): T } - Kontravarianta (in): Umožňuje používat typ a jeho nadtypy. Označuje se
in. Příklad:Comparator<in String>může pracovat sComparator<Any>. Používá se pro typy, které spotřebovávají hodnoty (například zápis do kolekce).interface Consumer<in T> { // in T - kontravariantní parametr fun consume(value: T) } - Invarianta: Typ v generickém parametru musí být přesně stejný. Toto je výchozí chování.
- Kovarience (out): Umožňuje používat typ a jeho podtypy. Označuje se
- Omezení typů (
where): Umožňuje omezit typ parametru tak, aby implementoval určité rozhraní nebo dědil z určité třídy.fun <T : Comparable<T>> max(a: T, b: T): T { // T musí implementovat Comparable return if (a > b) a else b } fun <T> process(item: T) where T : Runnable, T : Comparable<T> { item.run() // ... používání srovnatelnosti } - Hvězdička (star) projekce (
*): Používá se, když nejsou důležité konkrétní argumenty typu. Podobně jako<?>v Javě.fun printList(list: List<*>) { // Přijímá seznam jakéhokoliv typu for (item in list) { println(item) } }
Generické typy v Kotlinu používají ztrátu typu (type erasure), stejně jako v Javě. Informace o konkrétních typech parametrů se ztrácí během běhu. Pro práci s typy během běhu se používají reified typy.
- Reified typy (
reified): Jsou dostupné pouze pro inline funkce. Umožňují zachovat informace o typu parametru během běhu.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") } }