Rust nu are suport nativ pentru OOP, dar puteți utiliza aceste tehnici pentru a profita de paradigmă oricum.

Programarea orientată pe obiecte (OOP) simplifică proiectarea software-ului punând accent pe utilizarea obiectelor pentru a reprezenta entități și concepte din lumea reală. OOP încurajează mentenabilitatea prin încapsularea funcționalității în obiecte.

Rust este un limbaj flexibil care acceptă programarea funcțională și procedurală. Deși nu acceptă în mod nativ programarea orientată pe obiecte, puteți implementa concepte OOP folosind tipurile de date încorporate de Rust.

Încapsulare în rugină

Încapsularea presupune organizarea codului în unități autonome care ascund detaliile interne în timp ce expunerea unei interfețe publice pentru interacțiunea externă pentru a minimiza complexitatea și a îmbunătăți codul mentenabilitatea.

Puteți încapsula codul Rust cu module. Un modul este o colecție de elemente care includ funcții, structuri, enumerări și constante. Modulele Rust oferă funcționalitate pentru gruparea și definirea granițelor între părți ale unui program.

instagram viewer

Utilizarea modulelor pentru încapsularea datelor și a funcțiilor

Puteți defini un modul folosind mod cuvânt cheie urmat de un nume:

mod modulul_meu {
// elementele modulului merg aici
}

Puteți organiza modulele ierarhic prin imbricarea declarațiilor lor:

mod parent_module {
mod modulul_meu {
// elementele modulului merg aici
}
}

Apoi, puteți face referire la module imbricate cu ierarhia completă, separând fiecare modul cu două puncte duble, de exemplu, parent_module:: my_module.

În mod implicit, elementele din module sunt private și sunt accesibile numai codului din același modul. Dar puteți face publice modulele folosind cârciumă cuvânt cheie:

mod modulul_meu {
cârciumăfnfuncția_mea() {
// corpul funcției merge aici
}
}

Apoi puteți accesa funcția_mea din alte părți ale programului dvs.

Utilizarea trăsăturilor pentru a defini comportamentele

Un alt mod prin care Rust permite încapsularea este prin utilizarea trăsăturilor. Trăsăturile definesc comportamentele pe care tipurile le pot implementa și asigură că diferitele tipuri sunt conforme cu aceeași interfață.

cârciumătrăsăturăPrintabil {
fnimprimare(&de sine);
}

cârciumăstructGenul meu {
// Structurați câmpurile aici
}

impl Printabil pentru Genul meu {
fnimprimare(&de sine) {
// implementare aici
}
}

The Printabil trasatura are o imprimare metoda, iar Genul meu struct implementează Printabil trasatura prin implementarea imprimare metodă.

Folosind trăsături, vă puteți asigura că orice tip care implementează Printabil trasatura are o imprimare metodă. Acest lucru este la îndemână atunci când lucrați cu cod generic care trebuie să interopereze cu diferite tipuri care împărtășesc un comportament comun.

Moștenire în Rust

Moștenirea vă permite să definiți o clasă pe baza uneia diferite. Subclasa va moșteni proprietățile și metodele părintelui său.

În Rust, ești încurajat să folosești compoziția în loc de moștenire. Compoziția este un proces de creare a unor obiecte noi prin combinarea celor existente. În loc să creați o nouă clasă care moștenește funcționalitatea din clasa de bază, puteți crea o nouă clasă care conține o instanță a structurii de bază și câmpurile sale.

Crearea de noi tipuri prin combinarea tipurilor existente

Veți folosi enumări și structuri pentru a crea tipuri noi. Enumerările sunt utile pentru tipurile cu valori finite, iar structurile pot conține mai multe câmpuri.

Puteți crea un tip de enumerare pentru diferite tipuri de animale.

enumerareAnimal {
Pisică,
Câine,
Pasăre,
// ...
}

Alternativ, puteți crea o structură care să conțină câmpuri pentru fiecare tip de animal. Structurile pot conține enumerari și alte tipuri.

structAnimal {
Nume: Şir,
vârstă: u8,
animal_type: AnimalType,
}

enumerareAnimalType {
Pisică,
Câine,
Pasăre,
// ...
}

The Animal struct deține valori ale AnimalType tip de enumerare.

Puteți folosi trăsături pentru a implementa moștenirea și pentru a adăuga un comportament unui tip fără a crea unul nou.

trăsăturăA zbura {
fna zbura(&de sine);
}

Iată cum puteți implementa A zbura trăsătură pentru mai multe tipuri.

structPasăre {
Nume: Şir,
anvergura aripilor: f32,
}

impl A zbura pentru pasăre {
fna zbura(&de sine) {
println!("{} zboară!", de sine.Nume);
}
}

structAvion {
model: Şir,
viteza maxima: u32,
}

impl A zbura pentru avion {
fna zbura(&de sine) {
println!("{} zboară!", de sine.model);
}
}

The Pasăre și Avion structurile implementează A zbura trăsătură și tipăriți șiruri cu Println! macro.

Puteți apela la a zbura metoda pe ambele structuri fără a le cunoaște tipurile specifice.

fnprincipal() {
lăsa pasăre = pasăre {
Nume: Şir::din("Vultur"),
anvergura aripilor: 2.0,
};

lăsa avion = avion {
model: Şir::din(„Boeing 747”),
viteza maxima: 900,
};

lăsa obiecte_zburătoare: Vecdin Zboară> = vec![&pasăre, &avion];

pentru obiect în obiecte_zburătoare {
obiect.zbura();
}
}

The principal funcția instanțiază Avion și Pasăre tipuri. The obiecte_zburătoare vector este un vector al instanțelor obiectului, iar pentru bucla traversează vectorul și apelează a zbura metoda asupra instantelor.

Implementarea polimorfismului în Rust

O clasă sau tip este polimorfă dacă mai multe tipuri reprezintă o interfață. Deoarece trăsăturile oferă funcționalitatea pentru definirea comportamentelor în Rust, oferind în același timp o interfață comună pentru scrierea codului generic, puteți utiliza trăsăturile pentru a implementa polimorfismul.

Iată o trăsătură numită Desenabil care definește comportamentul pentru redarea obiectelor pe ecran:

trăsăturăDesenabil {
fna desena(&de sine);
}

Tipurile care implementează trăsătura Drawable pot accesa a desena funcţie.

structDreptunghi {
lăţime: u32,
înălţime: u32,
}

impl Desenabil pentru dreptunghi {
fna desena(&de sine) {
// Redați dreptunghiul pe ecran
}
}

Puteți scrie cod generic care desenează obiecte care implementează Desenabil trăsătură.

fndesen_obiect(obiect: &T) {
object.draw();
}

The desen_obiect funcția ia un tip generic T ca intrare care implementează Desenabil trasatura si numeste a desena metoda asupra trăsăturii. Diferite obiecte pot implementa Desenabil trăsătură și accesați funcționalitatea.

Implementarea abstracției în Rust

Abstracția este conceptul POO unde clasele și interfețele sunt accesibile pentru obiectele și tipurile specificate. Puteți implementa abstractizarea în Rust cu trăsături.

Iată un exemplu de trăsătură pentru un player media:

trăsăturăMass-media {
fnJoaca(&de sine);
}

Structuri și enumerari care implementează Mass-media trăsătura trebuie să ofere o implementare pentru Joaca metodă.

structCântec {
titlu: Şir,
artist: Şir,
}

impl Mass-media pentru Cântec {
fnJoaca(&de sine) {
println!(„Se redă melodia: {} de {}”, de sine.titlu, de sine.artist);
}
}

The Cântec struct implementează Mass-media trăsătură prin furnizarea unei implementări pentru Joaca metodă care imprimă un mesaj cu câmpurile din Cântec structuri către consolă.

fnprincipal() {
// Creați o instanță a structurii Song
lăsa cântec = cântec {
titlu: Şir::din("Rapsodie boema"),
artist: Şir::din("Regină"),
};

// Apelați metoda de redare pe instanța melodiei
song.play();
}

The cântec variabila este o instanță a Cântec struct, iar variabila poate accesa și apela Joaca metodă.

Organizarea codului Rust este ușoară

Programarea orientată pe obiecte ajută la organizarea codului. Datorită sistemului de module Rust, vă puteți organiza cu ușurință codul Rust în timp ce implementați conceptele OOP pentru aplicația dvs. pentru a vă menține codul organizat, gestionabil și intuitiv.