0Pricing
Learn Rust Coding · Leçon

Contraintes de traits

Contraignez les génériques avec des traits.

Contraintes de traits est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 3 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.

Rôle des contraintes de traits

Une contrainte de trait limite un type générique aux types qui implémentent un trait donné. Elle indique au compilateur quel comportement le type garantit.

Elle rend accessibles les méthodes du trait dans le code générique, tout en gardant la fonction utilisable avec de nombreux types.

Syntaxe de contrainte en ligne

La forme la plus simple place la contrainte juste après le paramètre de type : T: Trait. Ici, T doit implémenter Display pour pouvoir être affiché.

Dans la fonction, vous pouvez maintenant appeler toute méthode fournie par Display.

use std::fmt::Display;

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

Un trait personnalisé

Les contraintes fonctionnent également avec vos propres traits. Définissez un trait avec une méthode, puis imposez-le comme contrainte à une fonction générique.

Ce trait Summary exige une méthode summarize qui renvoie une chaîne.

trait Summary {
    fn summarize(&self) -> String;
}

Implémenter et imposer une contrainte

Implémentez le trait pour un type ; une fonction contrainte pourra alors accepter tout type qui l'implémente. La fonction appelle la méthode du trait sans connaître le type concret.

Ce programme complet affiche un résumé d'un Article.

trait Summary { fn summarize(&self) -> String; }

struct Article { title: String }

impl Summary for Article {
    fn summarize(&self) -> String {
        format!("Article: {}", self.title)
    }
}

fn notify<T: Summary>(item: &T) {
    println!("{}", item.summarize());
}

fn main() {
    let a = Article { title: String::from("Rust") };
    notify(&a);
}

Combiner des contraintes avec +

Exigez plusieurs traits à la fois en les reliant avec +. Ici, T doit implémenter à la fois Display et Clone.

La fonction peut alors afficher la valeur et également la cloner.

use std::fmt::Display;

fn process<T: Display + Clone>(value: T) {
    let copy = value.clone();
    println!("{}", copy);
}

<code>impl Trait</code> dans les arguments

La syntaxe impl Trait dans la position d'un argument est une forme abrégée d'une contrainte simple. item: &impl Summary signifie la même chose qu'un paramètre <T: Summary>.

Elle est concise pour les cas à un seul argument, mais offre moins de contrôle lorsque vous réutilisez le type.

trait Summary { fn summarize(&self) -> String; }

fn notify(item: &impl Summary) {
    println!("{}", item.summarize());
}

Renvoyer <code>impl Trait</code>

Vous pouvez également renvoyer impl Trait afin de masquer un type concret tout en garantissant qu'il implémente un trait. C'est pratique pour les fermetures et les itérateurs.

L'appelant sait seulement que le résultat implémente le trait indiqué.

fn make_adder(n: i32) -> impl Fn(i32) -> i32 {
    move |x| x + n
}

fn main() {
    let add5 = make_adder(5);
    println!("{}", add5(10));
}

Les contraintes activent les opérateurs

Les opérateurs correspondent à des traits : + nécessite Add, == nécessite PartialEq et les comparaisons nécessitent PartialOrd. Imposer ces contraintes permet au code générique d'utiliser les opérateurs.

Ici, la somme exige que T implémente Add avec lui-même.

use std::ops::Add;

fn sum<T: Add<Output = T>>(a: T, b: T) -> T {
    a + b
}

Méthodes par défaut des traits

Les traits peuvent fournir le corps par défaut de leurs méthodes. Les types qui les implémentent peuvent le remplacer ou utiliser la version par défaut. Les génériques contraints utilisent la version active.

Ce Summary possède un summarize par défaut que les types peuvent conserver tel quel.

trait Summary {
    fn summarize(&self) -> String {
        String::from("(no summary)")
    }
}

struct Note;
impl Summary for Note {}

Appel statique ou dynamique

Les contraintes de traits utilisent un appel statique : le compilateur choisit la méthode exacte au moment de la compilation grâce à la monomorphisation. En revanche, dyn Trait utilise un appel dynamique via une table virtuelle.

Les contraintes sont généralement plus rapides ; dyn échange de la vitesse contre des binaires plus petits et une plus grande flexibilité à l'exécution.

Contraintes sur les structures génériques

Les contraintes de traits ne se limitent pas aux fonctions. Vous pouvez les exiger lors de la définition d'une structure afin que toutes les instances satisfassent le trait.

Ici, chaque Sortable<T> garantit que ses éléments peuvent être comparés.

struct Sortable<T: PartialOrd> {
    items: Vec<T>,
}

Vérification rapide

Testez votre compréhension des contraintes de traits.

Récapitulatif

Les contraintes de traits limitent les types génériques afin que le compilateur autorise les méthodes et les opérateurs du trait. Combinez les traits avec + et utilisez impl Trait comme forme abrégée dans les arguments ou les valeurs de retour.

Les contraintes permettent un appel statique sans surcoût, contrairement à l'appel dynamique de dyn Trait.

Questions Fréquemment Posées

La leçon « Contraintes de traits » est-elle gratuite ?

Oui — le texte complet de « Contraintes de traits » 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 « Contraintes de traits » ?

Contraignez les génériques avec des traits. 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 3 sur 4.

Combien de temps prend la leçon « Contraintes de traits » ?

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