Statisk kontra dynamisk dispatch
Afvejninger
Statisk kontra dynamisk dispatch er en gratis Lær at programmere i Rust-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lær at programmere i Rust, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lær at programmere i Rust-kurset indeholder 4 lektioner i alt.
To måder at udføre dispatch på
Når du kalder en trait-metode, skal Rust afgøre, hvilken konkret implementering der skal køre. Der er to strategier: statisk dispatch (afgjort ved kompilering) og dynamisk dispatch (afgjort ved kørsel).
Statisk dispatch med generiske typer
Generiske funktioner bruger statisk dispatch. Compileren genererer en specialiseret kopi for hver konkret type — en proces, der kaldes monomorfisering.
trait Area { fn area(&self) -> f64; }
struct Square { s: f64 }
impl Area for Square { fn area(&self) -> f64 { self.s * self.s } }
fn print_area<T: Area>(shape: &T) {
println!("{}", shape.area());
}
fn main() {
print_area(&Square { s: 4.0 });
}Monomorfisering
For hver type, du kalder funktionen med, fremstiller compileren en dedikeret version af funktionen. Metodekaldet bliver til et direkte kald uden opslag, så det er lige så hurtigt som håndskrevet kode.
Dynamisk dispatch med dyn
Trait-objekter bruger dynamisk dispatch. Én funktion håndterer alle typer; metodeadressen findes ved kørsel via en vtable.
trait Area { fn area(&self) -> f64; }
struct Square { s: f64 }
impl Area for Square { fn area(&self) -> f64 { self.s * self.s } }
fn print_area(shape: &dyn Area) {
println!("{}", shape.area());
}
fn main() {
print_area(&Square { s: 4.0 });
}Vtablen
Et trait-objekt er en fed pointer: Den ene del peger på dataene, og den anden peger på en vtable, der oplister metodeadresserne. Hvert kald slår op i denne tabel.
Den ekstra indirektion er omkostningen ved kørsel.
Afvejning af hastighed
Statisk dispatch er hurtigere pr. kald og kan inlines, men genererer mere maskinkode. Dynamisk dispatch tilføjer en lille indirektion, men holder kodestørrelsen nede.
For de fleste apps er forskellen ubetydelig; vælg ud fra fleksibilitet.
Afvejning af kodestørrelse
Når du kalder en generisk funktion med mange typer, oprettes der mange kopier, hvilket kan gøre binærfilen større. Én dyn-funktion undgår denne gentagelse.
Derfor foretrækker biblioteker nogle gange trait-objekter internt.
Afvejning af fleksibilitet
Generiske typer kræver én konkret type pr. kaldested, så de kan ikke indeholde blandede typer i en samling. Det kan trait-objekter. Hvis du har brug for en samling med forskellige typer, er dynamisk dispatch svaret.
trait Area { fn area(&self) -> f64; }
struct Square { s: f64 }
struct Rect { w: f64, h: f64 }
impl Area for Square { fn area(&self) -> f64 { self.s * self.s } }
impl Area for Rect { fn area(&self) -> f64 { self.w * self.h } }
fn main() {
let shapes: Vec<Box<dyn Area>> = vec![Box::new(Square { s: 2.0 }), Box::new(Rect { w: 3.0, h: 4.0 })];
let total: f64 = shapes.iter().map(|s| s.area()).sum();
println!("{}", total);
}At kombinere begge dele
Du kan kombinere dem: En generisk funktion kan modtage impl Trait ved grænsen og gemme værdier som Box<dyn Trait> internt. Brug hver af dem, hvor den passer bedst.
En vejledning til valget
Hurtige tommelfingerregler:
- Én type pr. kald, og en hyppigt benyttet kodevej? Brug generiske typer (statisk).
- Blandede typer i en samling? Brug
dyn(dynamisk). - Bekymret for binærfilens størrelse? Hæld til
dyn.
Begge dele koster intet, hvor det tæller
Rust tilføjer aldrig overhead, som du ikke har bedt om. Generiske typer koster ikke noget ved kørsel; trait-objekter koster kun én pointerindirektion. Du vælger selv afvejningen.
Hurtigt tjek
Test din viden om dispatch.
Opsummering
Du har sammenlignet de to dispatch-typer:
- Statisk (generiske typer): monomorfiseret, hurtig, større binærfil, én type pr. kald
- Dynamisk (
dyn): opslag i vtable, fleksibel, mindre kode, tillader samlinger med blandede typer - Vælg ud fra behovet for fleksibilitet, ydeevne og binærfilens størrelse
Lær Rust med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 39
- Lektioner
- 144
Ofte stillede spørgsmål
Er lektionen “Statisk kontra dynamisk dispatch” gratis?
Ja — alle 3 lektioner i læringssporet Lær at programmere i Rust, inklusive “Statisk kontra dynamisk dispatch”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lær at programmere i Rust-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Statisk kontra dynamisk dispatch”?
Afvejninger Du øver dig i Lær at programmere i Rust med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Lær at programmere i Rust?
Der kræves ingen tidligere erfaring. Lær at programmere i Rust på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Statisk kontra dynamisk dispatch”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Lær at programmere i Rust-lektion?
Ja. Alle Lær at programmere i Rust-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Definition af traits
- Trait-objekter og dyn
- Statisk kontra dynamisk dispatch
- Standardmetoder