Lær at programmere i Rust · Lektion

Deref og ergonomi for wrappers

Få wrappers til at føles native.

Lektion 4 af 413 trin

Deref og ergonomi for wrappers er en gratis Lær at programmere i Rust-lektion på CoddyKit. Dette er lektion 4 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.

Problemet med brugervenlighed

En indpakning af en type giver sikkerhed, men fjerner bekvemmelighed: Pludselig skal du skrive wrapper.0.method() overalt og genimplementere metoder manuelt.

Traitet Deref kan genskabe meget af denne brugervenlighed ved at lade wrapperen opføre sig som den værdi, den indeholder.

Hvad Deref gør

Deref definerer, hvad *value giver, og driver operatoren .. Når du kalder en metode, som wrapperen ikke har, prøver compileren igen på deref-målet.

Dette automatiske trin kaldes deref-tvang.

use std::ops::Deref;
struct MyBox<T>(T);
impl<T> Deref for MyBox<T> {
    type Target = T;
    fn deref(&self) -> &T { &self.0 }
}

Deref-tvang i praksis

Når Deref er implementeret, fungerer kald til den indre types metoder direkte på wrapperen. Compileren indsætter .deref() for dig, indtil metoden bliver fundet.

use std::ops::Deref;
struct Name(String);
impl Deref for Name {
    type Target = String;
    fn deref(&self) -> &String { &self.0 }
}
fn main() {
    let n = Name("rustacean".to_string());
    println!("len = {}", n.len()); // String::len via deref
}

DerefMut til ændringsadgang

Deref giver kun delt adgang. Hvis du vil kalde metoder, der kræver &mut self, gennem wrapperen, skal du også implementere DerefMut, som returnerer en ændringsreference til den indre værdi.

use std::ops::{Deref, DerefMut};
struct Stack(Vec<i32>);
impl Deref for Stack {
    type Target = Vec<i32>;
    fn deref(&self) -> &Vec<i32> { &self.0 }
}
impl DerefMut for Stack {
    fn deref_mut(&mut self) -> &mut Vec<i32> { &mut self.0 }
}

Tvang ved funktionsgrænser

Deref-tvang gælder også argumenter. En &Name tvinges til &String, som selv tvinges til &str, så du kan sende wrapperen direkte til funktioner, der forventer den indre reference.

fn greet(who: &str) {
    println!("hi {}", who);
}
// greet(&name) works: &Name -> &String -> &str

Et kørbart eksempel på tvang

Dette program sender en wrapperreference, hvor der forventes et strengudsnit. De kædede deref-tvingninger sker lydløst på kaldstedet.

use std::ops::Deref;
struct Tag(String);
impl Deref for Tag {
    type Target = String;
    fn deref(&self) -> &String { &self.0 }
}
fn shout(s: &str) { println!("{}!", s.to_uppercase()); }
fn main() {
    let t = Tag("ship".to_string());
    shout(&t);
}

Misbrug ikke Deref

Rusts API-retningslinjer fraråder at implementere Deref for typer, der ikke reelt er intelligente pointere. Overdreven brug gør wrapperens tilgængelige metoder uforudsigelige og overrasker læserne.

Hvis newtypen findes for at begrænse et API, kan en ubetinget Deref lække netop de metoder, du ønskede at skjule.

AsRef som et målrettet alternativ

Når du kun har brug for eksplicit konvertering i stedet for automatisk tvang, skal du implementere AsRef. Kaldere skriver bevidst .as_ref(), så wrapperens egen overflade forbliver tydelig.

struct Path(String);
impl AsRef<str> for Path {
    fn as_ref(&self) -> &str { &self.0 }
}

Videresendelse af udvalgte metoder

For en begrænsende wrapper bør du foretrække selv at skrive netop de metoder, du vil eksponere. Så bevarer du fuld kontrol over API'et i stedet for at lække alt gennem Deref.

struct Counter(Vec<u8>);
impl Counter {
    fn len(&self) -> usize { self.0.len() }
    fn push(&mut self, b: u8) { self.0.push(b); }
}

Intelligente pointere bruger Deref

Standard-intelligente pointere som Box, Rc og Arc implementerer alle Deref. Derfor kan du kalde de indre metoder på dem uden ekstra syntaks. Dette er den legitime og tilsigtede brug af traitet.

use std::rc::Rc;
fn main() {
    let shared = Rc::new(String::from("data"));
    // Deref lets us call String methods directly
    println!("len = {}", shared.len());
}

Valg af strategi for brugervenlighed

Vælg ud fra hensigten. Brug Deref til ægte wrappers omkring intelligente pointere, AsRef til eksplicitte konverteringer af lånte værdier og manuel videresendelse, når en newtype skal begrænse API'et for den indre type.

Det forkerte valg skjuler enten for meget eller lækker for meget.

Hurtigt tjek

Find ud af, hvilken wrapper der bør have en Deref-implementering.

Opsummering

Deref og deref-tvang genskaber brugervenlighed i wrappers ved at lade operatoren . og referenceargumenter falde igennem til den indre værdi; DerefMut tilføjer ændringsadgang.

Begræns Deref til ægte intelligente pointere. Til begrænsende newtypes skal du bruge AsRef til eksplicitte konverteringer eller kun videresende de metoder, du vælger at eksponere.

Gratis at komme i gang

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 “Deref og ergonomi for wrappers” gratis?

Ja — alle 3 lektioner i læringssporet Lær at programmere i Rust, inklusive “Deref og ergonomi for wrappers”, 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 “Deref og ergonomi for wrappers”?

Få wrappers til at føles native. 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 4 af 4.

Hvor lang tid tager lektionen “Deref og ergonomi for wrappers”?

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

  1. Builder-mønstret
  2. Newtype-mønstret
  3. Type-State-buildere
  4. Deref og ergonomi for wrappers
← Tilbage til Lær at programmere i Rust