Middle
Cum să lucrezi cu tipurile generice în Kotlin?
sobes.tech AI
Răspuns de la AI
Tipurile generice în Kotlin permit crearea de clase, interfețe și funcții care lucrează cu date de diferite tipuri, păstrând siguranța tipurilor în timpul compilării.
Concepte principale și moduri de lucru:
- Declarația de clase și interfețe generice:
class Box<T>(val item: T) // Clasă generică cu parametru de tip T interface MyList<E> { // Interfață generică cu parametru de tip E fun add(element: E) fun get(index: Int): E } - Declarația de funcții generice:
fun <T> printAnything(value: T) { // Funcție generică cu parametru de tip T println(value) } - Crearea de instanțe ale tipurilor generice:
val intBox: Box<Int> = Box(123) // Specificarea unui tip concret (Int) val stringBox = Box("hello") // Compilatorul deduce tipul (String) - Variații: Permite definirea modului în care funcționează subtipurile cu tipuri generice.
- Covarianța (out): Permite utilizarea tipului și a subtipurilor sale. Se indică cu
out. Exemplu:List<out Any>poate conțineList<String>. Se folosește pentru tipuri care produc valori (de exemplu, citirea din colecții).interface Producer<out T> { // out T - parametru covariant fun produce(): T } - Contravarianța (in): Permite utilizarea tipului și a supertipurilor sale. Se indică cu
in. Exemplu:Comparator<in String>poate lucra cuComparator<Any>. Se folosește pentru tipuri care consumă valori (de exemplu, scrierea în colecții).interface Consumer<in T> { // in T - parametru contravariant fun consume(value: T) } - Invarianța: Tipul din parametrul generic trebuie să fie exact același. Aceasta este comportamentul implicit.
- Covarianța (out): Permite utilizarea tipului și a subtipurilor sale. Se indică cu
- Restricții de tipuri (
where): Permite limitarea tipului parametrului pentru a implementa anumite interfețe sau a moșteni o anumită clasă.fun <T : Comparable<T>> max(a: T, b: T): T { // T trebuie să implementeze Comparable return if (a > b) a else b } fun <T> process(item: T) where T : Runnable, T : Comparable<T> { item.run() // ... utilizarea comparabilității } - Proiecția cu stea (
*): Se folosește atunci când nu contează argumentele specifice ale tipului. Similar cu<?>în Java.fun printList(list: List<*>) { // Poate accepta o listă de orice tip for (item in list) { println(item) } }
Tipurile generice în Kotlin utilizează ștergerea tipurilor (type erasure), ca și în Java. Informația despre tipurile specifice se pierde în timpul execuției. Pentru a lucra cu tipuri în timpul execuției, se folosesc tipuri reificate.
- Tipuri reificate (
reified): Disponibile doar pentru funcții inline. Permite păstrarea informației despre tipul parametrului în timpul execuției.inline fun <reified T> checkType(value: Any) { // T - tip reificat if (value is T) { println("Valoarea este de tip T") } else { println("Valoarea nu este de tip T") } }