Learn Rust Coding · Leçon

Clauses where et contraintes multiples

Gardez les signatures complexes lisibles.

Leçon 4 sur 413 étapes

Clauses where et contraintes multiples est une leçon Learn Rust Coding 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 Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 4 leçons au total.

Quand les contraintes en ligne deviennent trop nombreuses

Les contraintes en ligne comme <T: Display + Clone, U: Debug + Default> deviennent difficiles à lire lorsqu'elles s'allongent. Rust propose la clause where comme solution plus claire.

Elle déplace les contraintes sous la signature, ce qui garde la liste des paramètres courte.

Clause <code>where</code> de base

Une clause where se place entre le type de retour et le corps. Chaque ligne indique un type et ses contraintes.

Ces deux signatures signifient exactement la même chose ; la forme avec where est simplement plus lisible.

use std::fmt::Display;

fn show<T>(value: T)
where
    T: Display,
{
    println!("{}", value);
}

Plusieurs contraintes dans <code>where</code>

Vous pouvez placer plusieurs contraintes, une par paramètre de type, en les séparant par des virgules. Chacune peut combiner des traits avec +.

Cela préserve la lisibilité d'une signature chargée, plutôt que de tout entasser en ligne.

use std::fmt::{Display, Debug};

fn report<T, U>(a: T, b: U)
where
    T: Display + Clone,
    U: Debug,
{
    println!("{} {:?}", a, b);
}

Un exemple complet

Ce programme utilise une clause where qui exige Display. Il s'exécute et affiche chaque argument avec une étiquette.

Remarquez que l'en-tête de la fonction reste clair, même avec la contrainte associée.

use std::fmt::Display;

fn label<T>(name: &str, value: T)
where
    T: Display,
{
    println!("{} = {}", name, value);
}

fn main() {
    label("age", 30);
    label("city", "Oslo");
}

Contraintes que le compilateur ne peut pas écrire en ligne

Certaines contraintes ne peuvent être écrites que dans une clause where, notamment celles qui portent sur des types associés ou référencés. La syntaxe en ligne ne peut pas exprimer where Vec<T>: Clone.

La forme avec where est donc strictement plus expressive.

fn duplicate<T>(items: Vec<T>) -> (Vec<T>, Vec<T>)
where
    Vec<T>: Clone,
{
    (items.clone(), items)
}

Combiner des traits standard

Dans les applications réelles, une contrainte courante combine l'ordre, la copie et l'affichage. Cette fonction générique max_of trouve l'élément le plus grand d'une tranche.

La clause where regroupe les trois traits dont dépend l'algorithme.

use std::fmt::Display;

fn max_of<T>(items: &[T]) -> &T
where
    T: PartialOrd + Display,
{
    let mut best = &items[0];
    for item in items {
        if item > best { best = item; }
    }
    best
}

Exécuter max_of

Voici la même idée dans un programme exécutable. La tranche d'entiers satisfait PartialOrd + Display ; l'appel peut donc être compilé et affiche le maximum.

La fonction fonctionnerait tout aussi bien avec des nombres à virgule flottante ou des caractères.

fn max_of<T>(items: &[T]) -> &T
where
    T: PartialOrd,
{
    let mut best = &items[0];
    for item in items {
        if item > best { best = item; }
    }
    best
}

fn main() {
    let nums = [3, 7, 1, 9, 4];
    println!("{}", max_of(&nums));
}

<code>where</code> sur les blocs <code>impl</code>

Les clauses where peuvent également être associées aux blocs impl. Cela ajoute une méthode uniquement lorsque le type stocké implémente Display.

Les instances dont le T n'est pas Display n'auront tout simplement pas cette méthode.

use std::fmt::Display;

struct Holder<T> { item: T }

impl<T> Holder<T>
where
    T: Display,
{
    fn print(&self) {
        println!("{}", self.item);
    }
}

De nombreuses contraintes à la fois

Les interfaces génériques réelles exigent souvent plusieurs traits par paramètre. Cette signature demande le clonage, le débogage et une valeur par défaut.

La clause where reste lisible malgré les trois contraintes imposées à un même type.

use std::fmt::Debug;

fn build<T>() -> T
where
    T: Default + Clone + Debug,
{
    let v = T::default();
    v.clone()
}

Choisir entre une contrainte en ligne et <code>where</code>

Utilisez des contraintes inline pour une ou deux contraintes simples. Passez à where lorsqu’il y a de nombreux paramètres, de longues listes de traits ou des contraintes portant sur des types complexes.

Les deux formes produisent un code identique ; le choix dépend uniquement de la lisibilité.

where avec des durées de vie

Une clause where peut répertorier les relations entre durées de vie en plus des contraintes de traits. Cela permet d’organiser les signatures génériques comportant ces deux types de contraintes.

Ici, la clause exige que T vive plus longtemps que la durée de vie 'a.

fn keep<'a, T>(value: &'a T) -> &'a T
where
    T: 'a,
{
    value
}

Vérification rapide

Vérifiez votre compréhension des clauses where et des contraintes multiples.

Récapitulatif

Une clause where déplace les contraintes de traits sous la signature, ce qui améliore la lisibilité lorsque le nombre de paramètres ou de traits augmente. Elle peut également exprimer des contraintes sur des types complexes et des durées de vie, ce que la syntaxe inline ne permet pas.

Les contraintes inline et celles de where sont compilées de manière identique ; choisissez donc la forme la plus claire à la lecture.

Gratuit pour commencer

Apprends Rust 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
39
Leçons
144

Questions Fréquemment Posées

La leçon « Clauses where et contraintes multiples » est-elle gratuite ?

Oui — le texte complet de « Clauses where et contraintes multiples » 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 Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Clauses where et contraintes multiples » ?

Gardez les signatures complexes lisibles. Tu pratiques Learn Rust Coding 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 Learn Rust Coding ?

Aucune expérience préalable n'est requise. Learn Rust Coding 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 « Clauses where et contraintes multiples » ?

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 Learn Rust Coding ?

Oui. Chaque leçon Learn Rust Coding 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 génériques
  2. Structures et énumérés génériques
  3. Contraintes de traits
  4. Clauses where et contraintes multiples
← Retour à Learn Rust Coding