Lär dig programmera i Rust · Lektion

where-satser och flera begränsningar

Gör komplexa signaturer lättare att läsa.

Lektion 4 av 413 steg

where-satser och flera begränsningar är en gratis lektion i Lär dig programmera i Rust på CoddyKit. Detta är lektion 4 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.

När inline-begränsningar blir svåröverskådliga

Inline-begränsningar som <T: Display + Clone, U: Debug + Default> blir svåra att läsa när de växer. Rust erbjuder satsen where som ett renare alternativ.

Den flyttar begränsningarna under signaturen, så att parameterlistan hålls kort.

Grundläggande where-sats

En where-sats placeras mellan returtypen och funktionskroppen. Varje rad anger en typ och dess begränsningar.

De här två signaturerna betyder exakt samma sak; formen med where är bara lättare att läsa.

use std::fmt::Display;

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

Flera begränsningar i where

Ni kan ange flera begränsningar, en per typparameter, separerade med kommatecken. Varje parameter kan kombinera traits med +.

Det gör en komplex signatur läsbar i stället för att allt kläms in inline.

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

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

Ett komplett exempel

Det här programmet använder en where-sats som kräver Display. Det körs och skriver ut varje argument med en etikett.

Lägg märke till hur funktionshuvudet förblir rent även när begränsningen är kopplad till det.

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");
}

Begränsningar som kompilatorn inte kan skriva inline

Vissa begränsningar kan bara skrivas i en where-sats, till exempel begränsningar på associerade eller refererade typer. Inline-syntaxen kan inte uttrycka where Vec<T>: Clone.

Formen med where är därför strikt mer uttrycksfull.

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

Kombinera standardtraits

En vanlig begränsning i verkliga program kombinerar ordning, kopiering och utskrift. Den här generiska max_of hittar det största elementet i en slice.

where-satsen samlar de tre traits som algoritmen bygger på.

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
}

Körning av max_of

Här är samma idé i ett körbart program. Slicen med heltal uppfyller PartialOrd + Display, så anropet kompileras och skriver ut det största värdet.

Funktionen skulle fungera lika bra med flyttal eller tecken.

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));
}

where på impl-block

where-satser kan också kopplas till impl-block. Det lägger till en metod endast när den lagrade typen implementerar Display.

Instanser vars T inte är Display har helt enkelt inte den här metoden.

use std::fmt::Display;

struct Holder<T> { item: T }

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

Många begränsningar på en gång

Generiska API:er i verkliga program kräver ofta flera traits per parameter. Den här signaturen kräver kloning, felsökning och ett standardvärde.

where-satsen håller koden läsbar trots tre begränsningar på en typ.

use std::fmt::Debug;

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

Välja inline eller where

Använd inline-begränsningar för en eller två enkla begränsningar. Byt till where när det finns många parametrar, långa trait-listor eller begränsningar på komplexa typer.

Båda kompileras till identisk kod; valet handlar enbart om läsbarhet.

where med livstider

En where-sats kan ange relationer mellan livstider tillsammans med trait-begränsningar. Det håller generiska signaturer med båda typerna av begränsningar organiserade.

Här kräver satsen att T lever längre än livstiden 'a.

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

Snabbtest

Testa er förståelse av where-satser och flera begränsningar.

Sammanfattning

En where-sats flyttar trait-begränsningar under signaturen och förbättrar läsbarheten när antalet parametrar eller trait-listornas längd ökar. Den kan också uttrycka begränsningar på komplexa typer och livstider som inline-syntaxen inte kan uttrycka.

Inline-begränsningar och where-begränsningar kompileras identiskt, så välj den form som är tydligast att läsa.

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 ”where-satser och flera begränsningar” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lär dig programmera i Rust, inklusive ”where-satser och flera 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 ”where-satser och flera begränsningar”?

Gör komplexa signaturer lättare att läsa. 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 4 av 4.

Hur lång tid tar lektionen ”where-satser och flera 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