Kotlin Academy · Leçon

Variance au site de déclaration

in et out

Leçon 2 sur 413 étapes

Variance au site de déclaration est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Kotlin Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Kotlin Academy comprend 4 leçons au total.

Le problème de la variance

List<String> est-elle une sorte de List<Any> ? Parfois oui, parfois non. La variance décrit la manière dont les types génériques sont liés lorsque leurs paramètres de type le sont. Kotlin utilise out et in pour exprimer cette relation.

Invariance par défaut

Par défaut, les types génériques sont invariants : Box<String> n’est PAS un Box<Any>, même si String est un sous-type du type le plus général. Cela empêche les opérations dangereuses.

class Box<T>(val value: T)

fun main() {
    val strBox = Box("hi")
    // val anyBox: Box<Any> = strBox // would not compile
    println(strBox.value)
}

Covariance avec out

Marquer un paramètre de type avec out le rend covariant : Producer<String> devient un sous-type de Producer<Any>. Le type ne peut apparaître que dans des positions de sortie, comme les types de retour.

class Producer<out T>(private val item: T) {
    fun produce(): T = item
}

fun main() {
    val strProducer: Producer<String> = Producer("hello")
    val anyProducer: Producer<Any> = strProducer
    println(anyProducer.produce())
}

Pourquoi out est sûr

Si une classe ne fait que produire, c’est-à-dire renvoyer, T sans jamais le consommer, considérer un Producer<String> comme un Producer<Any> est sûr, car chaque String qu’il renvoie est également une valeur du type le plus général.

out dans la bibliothèque standard

Le List<out E> en lecture seule de Kotlin est covariant, ce qui explique qu’un List<String> puisse être utilisé là où un List<Any> est attendu.

fun printAll(items: List<Any>) {
    items.forEach { println(it) }
}

fun main() {
    val names: List<String> = listOf("Ann", "Bob")
    printAll(names)
}

Contravariance avec in

Marquer un paramètre de type avec in le rend contravariant : Consumer<Any> devient un sous-type de Consumer<String>. Le type ne peut apparaître que dans des positions d’entrée, comme les paramètres.

class Consumer<in T> {
    fun consume(item: T) {
        println("Consumed $item")
    }
}

fun main() {
    val anyConsumer: Consumer<Any> = Consumer()
    val strConsumer: Consumer<String> = anyConsumer
    strConsumer.consume("hi")
}

Pourquoi in est sûr

Un consommateur qui accepte Any peut certainement accepter une String. Ainsi, un Consumer<Any> peut être utilisé partout où un Consumer<String> est nécessaire.

Le moyen mnémotechnique PECS

Retenez Producer étend, Consumer accepte un supertype ; en termes Kotlin : out pour les producteurs, c’est-à-dire la sortie, et in pour les consommateurs, c’est-à-dire l’entrée. Un type qui ne fait que produire T utilise out ; celui qui ne fait que recevoir T utilise in.

Combiner in et out

Un paramètre de type utilisé à la fois en entrée et en sortie, comme dans une liste modifiable, doit rester invariant. Les types Function illustrent les deux cas : les paramètres sont in et la valeur de retour est out.

fun main() {
    val f: (Number) -> Int = { it.toInt() }
    val g: (Int) -> Number = f
    println(g(3.0.let { Number::class; 5 }))
}

La variance au niveau de la déclaration se définit en un seul endroit

La variance au niveau de la déclaration est définie une seule fois, sur la classe elle-même avec in/out. Chaque utilisation de la classe bénéficie ensuite automatiquement de cette variance, contrairement à Java où vous répétez les caractères génériques à chaque utilisation.

Choisir in ou out

Demandez-vous si cette classe ne fait que produire T, auquel cas utilisez out, ne fait que consommer T, auquel cas utilisez in, ou fait les deux, auquel cas laissez-la invariante. Faire correspondre le modificateur au rôle rend vos types génériques flexibles et sûrs.

Vérification rapide

Qu’indique le modificateur out ?

Récapitulatif

Les types génériques sont invariants par défaut. Utilisez out pour la covariance lorsqu’un type ne fait que produire des valeurs, et in pour la contravariance lorsqu’il ne fait que consommer des valeurs. Retenez que les producteurs utilisent out et les consommateurs utilisent in. Vous allez maintenant appliquer la variance au point d’utilisation avec les projections de type.

Gratuit pour commencer

Apprends Kotlin avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
51
Leçons
203

Questions Fréquemment Posées

La leçon « Variance au site de déclaration » est-elle gratuite ?

Oui — le texte complet de « Variance au site de déclaration » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Kotlin Academy, passe à CoddyKit PRO. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Variance au site de déclaration » ?

in et out Tu pratiques Kotlin Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Kotlin Academy ?

Aucune expérience préalable n'est requise. Kotlin Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Variance au site de déclaration » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Kotlin Academy ?

Oui. Chaque leçon Kotlin Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Fonctions et classes génériques
  2. Variance au site de déclaration
  3. Variance au site d’utilisation
  4. Contraintes génériques
← Retour à Kotlin Academy