Rust heeft geen native ondersteuning voor OOP, maar je kunt deze technieken toch gebruiken om van het paradigma te profiteren.

Object-Oriented Programming (OOP) vereenvoudigt softwareontwerp door de nadruk te leggen op het gebruik van objecten om entiteiten en concepten uit de echte wereld weer te geven. OOP stimuleert onderhoudbaarheid door functionaliteit in objecten in te kapselen.

Rust is een flexibele taal die functioneel en procedureel programmeren ondersteunt. Hoewel het standaard geen objectgeoriënteerd programmeren ondersteunt, kunt u OOP-concepten implementeren met behulp van de ingebouwde gegevenstypen van Rust.

Inkapseling in roest

Inkapseling houdt in dat code wordt georganiseerd in op zichzelf staande eenheden die interne details verbergen het blootstellen van een openbare interface voor externe interactie om de complexiteit te minimaliseren en de code te verbeteren onderhoudbaarheid.

U kunt Rust-code inkapselen met modules. Een module is een verzameling items, waaronder functies, structuren, opsommingen en constanten. Rust-modules bieden functionaliteit voor het groeperen en definiëren van grenzen tussen delen van een programma.

instagram viewer

Modules gebruiken om gegevens en functies in te kapselen

U kunt een module definiëren met behulp van de mod trefwoord gevolgd door een naam:

mod mijn_module {
// module-items komen hier
}

U kunt modules hiërarchisch ordenen door hun declaraties te nesten:

mod ouder_module {
mod mijn_module {
// module-items komen hier
}
}

U kunt dan verwijzen naar geneste modules met de volledige hiërarchie, waarbij u elke module scheidt met een dubbele punt, bijvoorbeeld parent_module:: mijn_module.

Items binnen modules zijn standaard privé en alleen toegankelijk voor code binnen dezelfde module. Maar u kunt modules openbaar maken met behulp van de kroeg trefwoord:

mod mijn_module {
kroegfnmijn_functie() {
// function body komt hier
}
}

U kunt dan toegang krijgen mijn_functie uit andere onderdelen van uw programma.

Eigenschappen gebruiken om gedrag te definiëren

Een andere manier waarop Rust inkapseling mogelijk maakt, is door het gebruik van eigenschappen. Traits definiëren gedragingen die typen kunnen implementeren en zorgen ervoor dat verschillende typen voldoen aan dezelfde interface.

kroegkaraktereigenschapAfdrukbaar {
fnafdrukken(&zelf);
}

kroegstructuurMijn type {
// struct velden hier
}

impl Afdrukbaar voor Mijn type {
fnafdrukken(&zelf) {
// implementatie hier
}
}

De Afdrukbaar eigenschap heeft een afdrukken methode, en de Mijn type struct implementeert de Afdrukbaar eigenschap door het implementeren van de afdrukken methode.

Door eigenschappen te gebruiken, kunt u ervoor zorgen dat elk type dat de Afdrukbaar eigenschap heeft een afdrukken methode. Dit is handig bij het werken met generieke code die moet samenwerken met verschillende typen die een gemeenschappelijk gedrag delen.

Overerving in Roest

Met overerving kunt u een klasse definiëren op basis van een andere. De subklasse erft de eigenschappen en methoden van de bovenliggende klasse.

In Rust wordt je aangemoedigd om compositie te gebruiken in plaats van overerving. Compositie is een proces van het creëren van nieuwe objecten door bestaande te combineren. In plaats van een nieuwe klasse te maken die functionaliteit overerft van de basisklasse, kunt u een nieuwe structuur maken die een instantie van de basisstructuur en zijn velden bevat.

Nieuwe typen maken door bestaande typen te combineren

Je gebruikt enums en structs om nieuwe typen te maken. Enums zijn handig voor typen met eindige waarden, en structs kunnen meerdere velden bevatten.

U kunt een opsommingstype maken voor verschillende soorten dieren.

opsommingDier {
Kat,
Hond,
Vogel,
// ...
}

U kunt ook een structuur maken met velden voor elk diertype. Structuren kunnen opsommingen en andere typen bevatten.

structuurDier {
naam: Snaar,
leeftijd: u8,
animal_type: AnimalType,
}

opsommingDiersoort {
Kat,
Hond,
Vogel,
// ...
}

De Dier struct bevat waarden van de Diersoort opsomming type.

U kunt eigenschappen gebruiken om overerving te implementeren en gedrag aan een type toe te voegen zonder een nieuw type te maken.

karaktereigenschapVlieg {
fnvlieg(&zelf);
}

Hier ziet u hoe u de Vlieg eigenschap voor meerdere typen.

structuurVogel {
naam: Snaar,
spanwijdte: f32,
}

impl Vlieg voor Vogel {
fnvlieg(&zelf) {
println!("{} vliegt!", zelf.naam);
}
}

structuurVliegtuig {
model: Snaar,
maximale snelheid: u32,
}

impl Vlieg voor Vliegtuig {
fnvlieg(&zelf) {
println!("{} vliegt!", zelf.model);
}
}

De Vogel En Vliegtuig structs implementeren de Vlieg trait en print strings met de Println! macro.

U kunt bellen naar de vlieg methode op beide structuren zonder hun specifieke typen te kennen.

fnvoornaamst() {
laten vogel = vogel {
naam: Snaar::van("Adelaar"),
spanwijdte: 2.0,
};

laten vliegtuig = vliegtuig {
model: Snaar::van("Boeing 747"),
maximale snelheid: 900,
};

laten vliegende_objecten: Vecdyn Vlieg> = vec![&vogel, &vlak];

voor voorwerp in vliegende_objecten {
object.vlieg();
}
}

De voornaamst functie instantieert de Vliegtuig En Vogel soorten. De vliegende_objecten vector is een vector van de objectinstanties, en de voor lus doorloopt de vector en roept de vlieg methode op de instanties.

Polymorfisme implementeren in roest

Een klasse of type is polymorf als meerdere typen een interface vertegenwoordigen. Omdat traits de functionaliteit bieden voor het definiëren van gedrag in Rust, terwijl ze een gemeenschappelijke interface bieden voor het schrijven van generieke code, kun je Traits gebruiken om polymorfisme te implementeren.

Hier is een eigenschap genaamd Tekenbaar die het gedrag definieert voor het renderen van objecten op het scherm:

karaktereigenschapTekenbaar {
fntekenen(&zelf);
}

Typen die de eigenschap Drawable implementeren, hebben toegang tot de tekenen functie.

structuurRechthoek {
breedte: u32,
hoogte: u32,
}

impl Tekenbaar voor Rechthoek {
fntekenen(&zelf) {
// Render de rechthoek op het scherm
}
}

U kunt generieke code schrijven die objecten tekent die het Tekenbaar karaktereigenschap.

fnteken_voorwerp(object: &T) {
object.tekenen();
}

De teken_voorwerp functie heeft een generiek type T als invoer die de implementeert Tekenbaar eigenschap en roept de tekenen methode op de eigenschap. Verschillende objecten kunnen het implementeren Tekenbaar eigenschap en krijg toegang tot de functionaliteit.

Abstractie implementeren in Rust

Abstractie is OOP-concept waar klassen en interfaces toegankelijk zijn voor gespecificeerde objecten en typen. Je kunt abstractie in Rust implementeren met eigenschappen.

Hier is een voorbeeldeigenschap voor een mediaspeler:

karaktereigenschapMedia {
fntoneelstuk(&zelf);
}

Structuren en opsommingen die de implementeren Media eigenschap moet een implementatie bieden voor de toneelstuk methode.

structuurLiedje {
titel: Snaar,
artiest: Snaar,
}

impl Media voor Liedje {
fntoneelstuk(&zelf) {
println!("Nummer wordt afgespeeld: {} van {}", zelf.titel, zelf.artiest);
}
}

De Liedje struct implementeert de Media eigenschap door een implementatie te bieden voor de toneelstuk methode die een bericht afdrukt met de velden van het Liedje structs naar de console.

fnvoornaamst() {
// Maak een instantie van de songstructuur
laten lied = lied {
titel: Snaar::van("Bohemian Rhapsody"),
artiest: Snaar::van("Koningin"),
};

// Roep de afspeelmethode aan op de songinstantie
lied.spelen();
}

De liedje variabele is een instantie van de Liedje struct, en de variabele heeft toegang tot het toneelstuk methode.

Roestcode organiseren is eenvoudig

Objectgeoriënteerd programmeren helpt bij codeorganisatie. Dankzij het modulesysteem van Rust kunt u eenvoudig uw Rust-code organiseren terwijl u de OOP-concepten voor uw toepassing implementeert om uw code georganiseerd, beheersbaar en intuïtief te houden.