Middle
Comment travailler avec les types génériques en Kotlin?
sobes.tech IA
Réponse de l'IA
Les types génériques en Kotlin permettent de créer des classes, interfaces et fonctions qui manipulent des données de différents types tout en assurant la sécurité de type lors de la compilation.
Concepts clés et méthodes de travail :
- Déclaration de classes et interfaces génériques :
class Box<T>(val item: T) // Classe générique avec paramètre de type T interface MyList<E> { // Interface générique avec paramètre de type E fun add(element: E) fun get(index: Int): E } - Déclaration de fonctions génériques :
fun <T> printAnything(value: T) { // Fonction générique avec paramètre de type T println(value) } - Création d'instances de types génériques :
val intBox: Box<Int> = Box(123) // Spécification d'un type concret (Int) val stringBox = Box("hello") // Le compilateur infère le type (String) - Variantes : Permet de définir comment fonctionnent les sous-types avec des types génériques.
- Covariance (out) : Permet d'utiliser le type et ses sous-types. Indiqué par
out. Exemple :List<out Any>peut contenirList<String>. Utilisé pour les types qui produisent des valeurs (par exemple, lecture de collections).interface Producer<out T> { // out T - paramètre covariant fun produce(): T } - Contravariance (in) : Permet d'utiliser le type et ses super-types. Indiqué par
in. Exemple :Comparator<in String>peut fonctionner avecComparator<Any>. Utilisé pour les types qui consomment des valeurs (par exemple, écriture dans une collection).interface Consumer<in T> { // in T - paramètre contravariant fun consume(value: T) } - Invariance : Le type dans le paramètre générique doit être exactement le même. C'est le comportement par défaut.
- Covariance (out) : Permet d'utiliser le type et ses sous-types. Indiqué par
- Restrictions de types (
where) : Permet de limiter le type du paramètre pour qu'il implémente certaines interfaces ou hérite d'une classe spécifique.fun <T : Comparable<T>> max(a: T, b: T): T { // T doit implémenter Comparable return if (a > b) a else b } fun <T> process(item: T) where T : Runnable, T : Comparable<T> { item.run() // ... utilisation de la comparabilité } - Projection étoile (
*) : Utilisée lorsque l'on ne se soucie pas des arguments spécifiques du type. Semblable à<?>en Java.fun printList(list: List<*>) { // Peut accepter une liste de n'importe quel type for (item in list) { println(item) } }
Les types génériques en Kotlin utilisent l'effacement de type (type erasure), comme en Java. L'information sur les types spécifiques est perdue en temps d'exécution. Pour travailler avec des types en temps d'exécution, on utilise des types reifiés.
- Types reifiés (
reified) : Disponibles uniquement pour les fonctions inline. Permettent de conserver l'information du type du paramètre en temps d'exécution.inline fun <reified T> checkType(value: Any) { // T - type reifié if (value is T) { println("Le valeur est du type T") } else { println("Le valeur n'est pas du type T") } }