0Pricing
Kotlin Academy · Leçon

Contraintes génériques

Définir des bornes pour les paramètres de type

Contraintes génériques est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 4 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.

Contraindre les paramètres de type

Parfois, un type générique ne doit accepter que certains types, par exemple des types comparables ou dérivés d’un type de base. Les contraintes génériques définissent une borne supérieure pour un paramètre de type.

La borne supérieure par défaut

Sans contrainte, la borne supérieure d’un paramètre de type est Any? : il accepte donc n’importe quel type, y compris les types pouvant être nuls. Pour n’autoriser que les types non nuls, liez-le à Any.

fun <T : Any> requireNonNull(value: T): T {
    return value
}

fun main() {
    println(requireNonNull(42))
}

Une seule borne supérieure

Utilisez T : Bound pour exiger que T soit un sous-type de Bound. Vous pouvez ainsi appeler les membres de la borne à l’intérieur de la fonction.

fun <T : Number> sumDoubled(a: T, b: T): Double {
    return a.toDouble() * 2 + b.toDouble() * 2
}

fun main() {
    println(sumDoubled(3, 4))
    println(sumDoubled(1.5, 2.5))
}

Borne Comparable

Une borne courante est Comparable<T>, qui vous permet de comparer des éléments avec <, > ou compareTo.

fun <T : Comparable<T>> maxOf2(a: T, b: T): T {
    return if (a > b) a else b
}

fun main() {
    println(maxOf2(3, 9))
    println(maxOf2("apple", "banana"))
}

Appeler les membres de la borne

Dans un type générique contraint, le compilateur sait que T possède l’API de la borne. Vous pouvez donc appeler directement ces méthodes sans effectuer de conversion de type.

fun <T : CharSequence> describe(value: T): String {
    return "Length is ${value.length}"
}

fun main() {
    println(describe("hello"))
    println(describe(StringBuilder("hi")))
}

Plusieurs bornes avec where

Pour utiliser plusieurs bornes, employez la clause where. T doit alors respecter ALL les contraintes indiquées.

fun <T> copyWhenValid(value: T): T
    where T : CharSequence, T : Comparable<T> {
    return value
}

fun main() {
    println(copyWhenValid("text"))
}

Bornes sur les classes

Les contraintes s’appliquent également aux classes génériques : elles limitent les types avec lesquels la classe peut être instanciée.

class NumberBox<T : Number>(val value: T) {
    fun asDouble(): Double = value.toDouble()
}

fun main() {
    val box = NumberBox(10)
    println(box.asDouble())
}

La contrainte permet des opérations

L’objectif d’une contrainte est précisément de rendre des opérations disponibles. Sans T : Number, vous ne pourriez pas appeler toDouble() ; la borne garantit que la méthode existe.

Une borne non nulle en pratique

Une contrainte vers Any rejette les arguments pouvant être nuls au moment de la compilation : c’est un moyen pratique d’exiger des types génériques non nuls.

fun <T : Any> firstNonNull(a: T, b: T): T = a

fun main() {
    println(firstNonNull("x", "y"))
    // firstNonNull(null, "y") would not compile
}

Combiner avec la variance

Les contraintes et la variance résolvent des problèmes différents : la variance (in/out) contrôle les relations de sous-typage, tandis que les contraintes (bornes :, where) limitent les types autorisés. Vous pouvez les utiliser ensemble.

Concevoir de bonnes contraintes

Ajoutez une contrainte uniquement lorsque vous avez besoin d’une capacité du type. Des contraintes excessives réduisent la réutilisabilité ; des contraintes insuffisantes imposent des conversions de type. Utilisez la borne la plus générale qui fournit les opérations nécessaires.

Vérification rapide

Comment exigez-vous qu’un paramètre de type respecte plusieurs bornes ?

Récapitulatif

Les contraintes génériques définissent des bornes supérieures avec T : Bound (ou where pour plusieurs bornes), rendent disponibles les opérations de la borne et excluent les types incompatibles. Une borne vers Any exige un type non nul. Combinées à la variance, les contraintes vous permettent de concevoir des types génériques sûrs et expressifs. Vous avez ainsi terminé le cours sur les génériques et la variance.

Questions Fréquemment Posées

La leçon « Contraintes génériques » est-elle gratuite ?

Oui — le texte complet de « Contraintes génériques » 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 « Contraintes génériques » ?

Définir des bornes pour les paramètres de type 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 4 sur 4.

Combien de temps prend la leçon « Contraintes génériques » ?

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