Lär dig programmera i Rust · Lektion

Trait-begränsningar

Begränsa generics med traits.

Lektion 3 av 413 steg

Trait-begränsningar är en gratis lektion i Lär dig programmera i Rust på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lär dig programmera i Rust, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lär dig programmera i Rust innehåller totalt 4 lektioner.

Vad trait-begränsningar gör

En trait-begränsning begränsar en generisk typ till typer som implementerar en viss trait. Den talar om för kompilatorn vilket beteende typen garanterar.

Det gör traitens metoder tillgängliga i den generiska koden samtidigt som funktionen kan användas med många typer.

Syntax för inbyggda begränsningar

Den enklaste formen placerar begränsningen direkt efter typparametern: T: Trait. Här måste T implementera Display så att den kan skrivas ut.

Inuti funktionen kan ni nu anropa alla metoder som Display tillhandahåller.

use std::fmt::Display;

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

En anpassad trait

Begränsningar fungerar även med era egna traits. Definiera en trait med en metod och begränsa sedan en generisk funktion med den.

Den här Summary-traiten kräver en summarize-metod som returnerar en sträng.

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

Implementera och begränsa

Implementera traiten för en typ. Därefter kan en begränsad funktion ta emot alla typer som implementerar den. Funktionen anropar trait-metoden utan att känna till den konkreta typen.

Det här kompletta programmet skriver ut en sammanfattning av en 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);
}

Kombinera begränsningar med +

Kräv flera traits samtidigt genom att sammanfoga dem med +. Här måste T implementera både Display och Clone.

Funktionen kan då skriva ut värdet och även klona det.

use std::fmt::Display;

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

impl Trait i argument

Syntaxen impl Trait på argumentposition är en kortform för en enkel begränsning. item: &impl Summary betyder samma sak som en parameter av typen <T: Summary>.

Den är kortfattad när det bara finns ett argument, men ger mindre kontroll när typen återanvänds.

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

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

Returnera impl Trait

Ni kan också returnera impl Trait för att dölja en konkret typ och samtidigt ange att den implementerar ett trait. Det är praktiskt för closures och iteratorer.

Anroparen vet bara att resultatet implementerar det angivna traitet.

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

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

Begränsningar aktiverar operatorer

Operatorer motsvarar traits: + kräver Add, == kräver PartialEq och jämförelser kräver PartialOrd. Genom att använda dessa som begränsningar kan generisk kod använda operatorerna.

Här kräver summeringen att T implementerar Add med sig själv.

use std::ops::Add;

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

Standardmetoder i traits

Traits kan tillhandahålla standardimplementationer av metoder. Den som implementerar traitet kan skriva över dem eller använda standardimplementationen. Generiska typer med begränsningar använder den implementation som gäller.

Det här Summary har en standardimplementation av summarize som typer kan behålla oförändrad.

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

struct Note;
impl Summary for Note {}

Statisk kontra dynamisk dispatch

Trait-begränsningar använder statisk dispatch: kompilatorn väljer den exakta metoden vid kompileringen genom monomorfisering. dyn Trait använder däremot dynamisk dispatch via en vtable.

Begränsningar är vanligtvis snabbare; dyn byter hastighet mot mindre binärfiler och flexibilitet vid körning.

Begränsningar på generiska structar

Trait-begränsningar är inte begränsade till funktioner. Ni kan kräva dem när ni definierar en struct, så att alla instanser uppfyller traitet.

Här garanterar varje Sortable<T> att dess element kan jämföras.

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

Snabbtest

Testa er förståelse av trait-begränsningar.

Sammanfattning

Trait-begränsningar begränsar generiska typer så att kompilatorn tillåter traitets metoder och operatorer. Kombinera traits med + och använd impl Trait som kortform i argument eller returvärden.

Begränsningar ger statisk dispatch utan extra kostnad, till skillnad från dynamisk dispatch med dyn Trait.

Gratis att börja

Lär dig Rust med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
39
Lektioner
144

Vanliga frågor

Är lektionen ”Trait-begränsningar” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lär dig programmera i Rust, inklusive ”Trait-begränsningar”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lär dig programmera i Rust innehåller totalt 4 lektioner.

Vad lär jag mig i ”Trait-begränsningar”?

Begränsa generics med traits. Ni övar på Lär dig programmera i Rust med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Lär dig programmera i Rust?

Du behöver inga förkunskaper. Utbildningen i Lär dig programmera i Rust på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Trait-begränsningar”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Lär dig programmera i Rust-lektionen?

Ja. Varje Lär dig programmera i Rust-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Generiska funktioner
  2. Generiska structs och enum-typer
  3. Trait-begränsningar
  4. where-satser och flera begränsningar
← Tillbaka till Lär dig programmera i Rust