Les generics en Kotlin : comment arrêter d'avoir peur des chevrons et écrire du code propre

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi les generics ne font pas peur, mais sont pratiques

\n\n

Imaginez que vous écrivez une classe « Boîte ». Vous pouvez y mettre n'importe quoi : un livre, une pomme, un téléphone. Mais si vous la faites pour Object, à chaque fois que vous en retirez quelque chose, vous devrez faire as? Book et prier pour ne pas tomber sur une ClassCastException. Ça vous dit quelque chose ?

\n\n

C'est là qu'interviennent les generics (génériques) — un puissant mécanisme de typage en Kotlin qui permet d'écrire du code flexible sans sacrifier la sécurité des types. Dans cet article, nous allons explorer les generics en Kotlin du simple au complexe : classes de base, fonctions, variance (in/out), types réifiés et projections stellaires. Vous apprendrez à rendre votre code plus propre et le compilateur votre meilleur allié.

\n\n

Cet article est préparé pour le portail éducatif pythonlib.ru — votre guide dans le monde des langages de programmation modernes.

\n\n

1. Les bases : qu'est-ce que les generics en Kotlin ?

\n\n

Les generics (types génériques) permettent de paramétrer des classes, des interfaces et des fonctions avec un type qui sera spécifié lors de l'utilisation. Cela évite la duplication de code et donne un contrôle sur les types au moment de la compilation.

\n\n

Regardez cet exemple simple :

\n\n
class Box<T>(val item: T)\n\nfun main() {\n    val bookBox = Box<String>("Kotlin in Action")\n    val intBox = Box<Int>(42)\n    // Le compilateur connaît le type !\n    val title: String = bookBox.item\n}
\n\n

Points clés :

\n
    \n
  • <T> — paramètre de type (peut être n'importe quelle lettre, mais par convention T, R, E, K, V).
  • \n
  • Le type est fixé lors de la création de l'objet — pas de casts à l'exécution.
  • \n
  • Les generics ne fonctionnent qu'au moment de la compilation (type erasure), mais Kotlin ajoute la « réification » (nous y reviendrons).
  • \n
\n\n

Fonctions génériques

\n

Le typage en Kotlin fonctionne aussi pour les fonctions. Par exemple, une fonction qui retourne le premier élément d'une liste :

\n\n
fun <T> firstItem(list: List<T>): T? = list.firstOrNull()\n\nfun main() {\n    val numbers = listOf(1, 2, 3)\n    val first: Int? = firstItem(numbers) // T = Int\n    println(first) // 1\n}
\n\n

Notez que Kotlin peut déduire le type du contexte — il n'est pas nécessaire d'écrire firstItem<Int>(numbers).

\n\n

2. Variance : in et out — comment ne pas casser la sécurité des types

\n\n

Le sujet le plus difficile pour les débutants est la variance (variabilité). Elle répond à la question : est-ce que List<String> peut être un sous-type de List<Any> ?

\n\n

En Java, cela se résout avec les wildcards (? extends / ? super). En Kotlin, avec out et in.

\n\n

out (covariance) — lecture seule

\n

L'annotation out signifie que le type générique ne peut être que « fourni » (retourné par les méthodes). Exemple — List<out T>.

\n\n
interface Source<out T> {\n    fun next(): T  // OK : T en sortie\n    // fun add(item: T) // Erreur ! T en entrée interdit\n}\n\nfun demo(source: Source<String>) {\n    val anySource: Source<Any> = source // out permet cela\n}
\n\n

Pourquoi est-ce sûr ? Si nous ne pouvons que lire des String depuis la source, alors on peut la considérer comme une source de Any.

\n\n

in (contravariance) — écriture seule

\n

in — l'inverse : le type ne peut être qu'en entrée. L'exemple classique est Comparable.

\n\n
interface Comparable<in T> {\n    operator fun compareTo(other: T): Int\n}\n\nfun demo(comp: Comparable<Number>) {\n    val intComp: Comparable<Int> = comp // in permet cela\n}
\n\n

Si Comparable<Number> sait comparer n'importe quel nombre, alors il comparera certainement aussi Int.

\n\n

in out (invariance) — par défaut

\n

Si ni in ni out n'est spécifié, le type est inv

Blogs

Book Recommendations