Rust mangler opprinnelig støtte for OOP, men du kan bruke disse teknikkene for å dra nytte av paradigmet uansett.

Objektorientert programmering (OOP) forenkler programvaredesign ved å legge vekt på bruken av objekter for å representere virkelige enheter og konsepter. OOP oppmuntrer til vedlikehold ved å kapsle inn funksjonalitet i objekter.

Rust er et fleksibelt språk som støtter funksjonell og prosedyreprogrammering. Selv om den ikke støtter objektorientert programmering, kan du implementere OOP-konsepter ved å bruke Rusts innebygde datatyper.

Innkapsling i Rust

Innkapsling innebærer å organisere kode i selvstendige enheter som skjuler interne detaljer mens eksponere et offentlig grensesnitt for ekstern interaksjon for å minimere kompleksiteten og forbedre koden vedlikeholdbarhet.

Du kan kapsle inn rustkode med moduler. En modul er en samling av elementer inkludert funksjoner, strukturer, oppregninger og konstanter. Rustmoduler gir funksjonalitet for gruppering og definering av grenser mellom deler av et program.

instagram viewer

Bruke moduler til å kapsle inn data og funksjoner

Du kan definere en modul ved å bruke mod nøkkelord etterfulgt av et navn:

mod min_modul {
// modulelementer går her
}

Du kan organisere moduler hierarkisk ved å neste erklæringene deres:

mod foreldremodul {
mod min_modul {
// modulelementer går her
}
}

Du kan deretter referere til nestede moduler med hele hierarkiet, og skille hver modul med et dobbelt kolon, for eksempel, foreldremodul:: min_modul.

Som standard er elementer i moduler private og kun tilgjengelige for kode innenfor samme modul. Men du kan gjøre moduler offentlige ved å bruke pub nøkkelord:

mod min_modul {
pubfnmin_funksjon() {
// function body går her
}
}

Du kan da få tilgang min_funksjon fra andre deler av programmet.

Bruke egenskaper for å definere atferd

En annen måte Rust muliggjør innkapsling på er gjennom bruk av egenskaper. Egenskaper definerer atferd som typer kan implementere og sikrer at forskjellige typer samsvarer med samme grensesnitt.

pubtrekkUtskrivbar {
fnskrive ut(&selv-);
}

pubstrukturMin type {
// struct-felt her
}

impl Utskrivbar til Min type {
fnskrive ut(&selv-) {
// implementering her
}
}

De Utskrivbar egenskap har en skrive ut metoden, og Min type struct implementerer Utskrivbar egenskap ved å implementere skrive ut metode.

Ved å bruke egenskaper kan du sikre at enhver type som implementerer Utskrivbar egenskap har en skrive ut metode. Dette er nyttig når du arbeider med generisk kode som må samvirke med forskjellige typer som deler en felles atferd.

Arv i Rust

Arv lar deg definere en klasse basert på en annen. Underklassen vil arve egenskapene og metodene til overordnet.

I Rust oppfordres du til å bruke komposisjon i stedet for arv. Komposisjon er en prosess for å lage nye objekter ved å kombinere eksisterende. I stedet for å lage en ny klasse som arver funksjonalitet fra basisklassen, kan du lage en ny struktur som inneholder en forekomst av basisstrukturen og dens felt.

Opprette nye typer ved å kombinere eksisterende typer

Du vil bruke oppsummeringer og strukturer for å lage nye typer. Enums er nyttige for typer med endelige verdier, og strukturer kan inneholde flere felt.

Du kan lage en opptegningstype for forskjellige typer dyr.

enumDyr {
Katt,
Hund,
Fugl,
// ...
}

Alternativt kan du lage en struktur som inneholder felt for hver dyretype. Strukturer kan inneholde enums og andre typer.

strukturDyr {
Navn: String,
alder: u8,
animal_type: AnimalType,
}

enumAnimalType {
Katt,
Hund,
Fugl,
// ...
}

De Dyr struct inneholder verdiene til AnimalType oppregningstype.

Du kan bruke egenskaper til å implementere arv og legge til atferd til en type uten å opprette en ny.

trekkFly {
fnfly(&selv-);
}

Her er hvordan du kan implementere Fly egenskap for flere typer.

strukturFugl {
Navn: String,
vingespenn: f32,
}

impl Fly til Fugl {
fnfly(&selv-) {
println!("{} flyr!", selv-.Navn);
}
}

strukturFly {
modell: String,
maksimal hastighet: u32,
}

impl Fly til Fly {
fnfly(&selv-) {
println!("{} flyr!", selv-.modell);
}
}

De Fugl og Fly strukturer implementere Fly egenskap og trykk strenger med Skriv ut! makro.

Du kan ringe til fly metode på begge strukturer uten å kjenne deres spesifikke typer.

fnhoved-() {
la fugl = Fugl {
Navn: String::fra("Ørn"),
vingespenn: 2.0,
};

la plan = Plane {
modell: String::fra("Boeing 747"),
maksimal hastighet: 900,
};

la flyvende_objekter: Vecdyn Fly> = vec![&fugl, &fly];

til gjenstand i flying_objects {
objekt.fly();
}
}

De hoved- funksjonen instansierer Fly og Fugl typer. De flyvende_objekter vektor er en vektor av objektforekomstene, og til loop går gjennom vektoren og kaller fly metode på forekomstene.

Implementering av polymorfisme i rust

En klasse eller type er polymorf hvis flere typer representerer et grensesnitt. Siden egenskaper gir funksjonaliteten for å definere atferd i Rust, samtidig som de gir et felles grensesnitt for å skrive generisk kode, kan du bruke Traits til å implementere polymorfisme.

Her er en egenskap som heter Tegnbar som definerer oppførselen for gjengivelse av objekter på skjermen:

trekkTegnbar {
fntegne(&selv-);
}

Typer som implementerer Drawable-trekket kan få tilgang til tegne funksjon.

strukturRektangel {
bredde: u32,
høyde: u32,
}

impl Tegnbar til Rektangel {
fntegne(&selv-) {
// Gjengi rektangelet på skjermen
}
}

Du kan skrive generisk kode som tegner objekter som implementerer Tegnbar trekk.

fntegne_objekt(objekt: &T) {
object.draw();
}

De tegne_objekt funksjon tar en generisk type T som innspill som implementerer Tegnbar egenskap og kaller den tegne metode på egenskapen. Ulike objekter kan implementere Tegnbar egenskap og tilgang til funksjonaliteten.

Implementering av abstraksjon i rust

Abstraksjon er OOP-konsept der klasser og grensesnitt er tilgjengelige for spesifiserte objekter og typer. Du kan implementere abstraksjon i Rust med egenskaper.

Her er et eksempeltrekk for en mediespiller:

trekkMedia {
fnspille(&selv-);
}

Strukturer og opptegnelser som implementerer Media egenskap må gi en implementering for spille metode.

strukturSang {
tittel: String,
kunstner: String,
}

impl Media til Sang {
fnspille(&selv-) {
println!("Spiller sang: {} av {}", selv-.tittel, selv-.kunstner);
}
}

De Sang struct implementerer Media egenskap ved å gi en implementering for spille metode som skriver ut en melding med feltene til Sang strukturer til konsollen.

fnhoved-() {
// Lag en forekomst av sangstrukturen
la sang = sang {
tittel: String::fra("Bohemian Rhapsody"),
kunstner: String::fra("Dronning"),
};

// Kalle avspillingsmetoden på sangforekomsten
sang.spill();
}

De sang variabel er en forekomst av Sang struct, og variabelen kan få tilgang til og kalle spille metode.

Det er enkelt å organisere rustkode

Objektorientert programmering hjelper med kodeorganisering. Takket være Rusts modulsystem kan du enkelt organisere Rust-koden din mens du implementerer OOP-konseptene for applikasjonen din for å holde koden organisert, håndterbar og intuitiv.