Rust няма собствена поддръжка за OOP, но можете да използвате тези техники, за да се възползвате от парадигмата така или иначе.

Обектно-ориентираното програмиране (ООП) опростява дизайна на софтуера, като набляга на използването на обекти за представяне на обекти и концепции от реалния свят. OOP насърчава поддържаемостта чрез капсулиране на функционалност в обектите.

Rust е гъвкав език, който поддържа функционално и процедурно програмиране. Въпреки че не поддържа първоначално обектно-ориентирано програмиране, можете да внедрите OOP концепции, като използвате вградените типове данни на Rust.

Капсулиране в Rust

Капсулирането включва организиране на код в самостоятелни единици, които скриват вътрешни детайли, докато излагане на публичен интерфейс за външно взаимодействие за минимизиране на сложността и подобряване на кода ремонтопригодност.

Можете да капсулирате кода на Rust с модули. Модулът е колекция от елементи, включително функции, структури, преброявания и константи. Модулите на Rust осигуряват функционалност за групиране и определяне на граници между части от програма.

instagram viewer

Използване на модули за капсулиране на данни и функции

Можете да дефинирате модул с помощта на мод ключова дума, последвана от име:

мод my_module {
// елементите на модула отиват тук
}

Можете да организирате модулите йерархично чрез влагане на техните декларации:

мод родителски_модул {
мод my_module {
// елементите на модула отиват тук
}
}

След това можете да се обърнете към вложените модули с пълната йерархия, като разделяте всеки модул с двойно двоеточие, например, родителски_модул:: моят_модул.

По подразбиране елементите в модулите са частни и достъпни само за код в рамките на същия модул. Но можете да направите модулите публични, като използвате кръчма ключова дума:

мод my_module {
кръчмаfnмоята_функция() {
// тялото на функцията отива тук
}
}

След това можете да получите достъп моята_функция от други части на вашата програма.

Използване на черти за определяне на поведения

Друг начин, по който Rust позволява капсулиране, е чрез използването на характеристики. Характеристиките определят поведението, което типовете могат да реализират и гарантират, че различните типове отговарят на един и същ интерфейс.

кръчмаХарактерна чертаВъзможност за печат {
fnпечат(&себе си);
}

кръчмаструктураMyType {
// struct полета тук
}

импл Възможност за печат за MyType {
fnпечат(&себе си) {
// изпълнение тук
}
}

The Възможност за печат черта има a печат метод и MyType struct изпълнява Възможност за печат черта чрез прилагане на печат метод.

Използвайки характеристики, можете да гарантирате, че всеки тип, който прилага Възможност за печат черта има a печат метод. Това е удобно, когато работите с общ код, който трябва да взаимодейства с различни типове, споделящи общо поведение.

Наследство в Руст

Наследяването ви позволява да дефинирате един клас въз основа на различен. Подкласът ще наследи свойствата и методите на своя родител.

В Rust се препоръчва да използвате композиция вместо наследяване. Композицията е процес на създаване на нови обекти чрез комбиниране на съществуващи. Вместо да създавате нов клас, който наследява функционалност от базовия клас, можете да създадете нова структура, която съдържа екземпляр на базовата структура и нейните полета.

Създаване на нови типове чрез комбиниране на съществуващи типове

Ще използвате enum и структури, за да създавате нови типове. Енумите са удобни за типове с крайни стойности, а структурите могат да съдържат множество полета.

Можете да създадете тип enum за различни видове животни.

изброяванеЖивотно {
котка,
куче,
птица,
// ...
}

Като алтернатива можете да създадете структура, съдържаща полета за всеки животински тип. Структурите могат да съдържат enum и други типове.

структураЖивотно {
име: низ,
възраст: u8,
тип_животно: Тип животно,
}

изброяванеAnimalType {
котка,
куче,
птица,
// ...
}

The Животно struct съдържа стойности на AnimalType тип изброяване.

Можете да използвате черти, за да приложите наследяване и да добавите поведение към тип, без да създавате нов.

Характерна чертаЛетя {
fnлетя(&себе си);
}

Ето как можете да приложите Летя черта за множество типове.

структураптица {
име: низ,
размах на крилата: f32,
}

импл Летя за птица {
fnлетя(&себе си) {
println!(„{} лети!“, себе си.име);
}
}

структураСамолет {
модел: низ,
максимална скорост: u32,
}

импл Летя за Самолет {
fnлетя(&себе си) {
println!(„{} лети!“, себе си.модел);
}
}

The птица и Самолет структурите изпълняват Летя черта и печатни низове с Println! макрос.

Можете да се обадите на летя метод и на двете структури, без да познава конкретните им типове.

fnосновен() {
позволявам птица = птица {
име: низ::от("Орел"),
размах на крилата: 2.0,
};

позволявам равнина = равнина {
модел: низ::от("Боинг 747"),
максимална скорост: 900,
};

позволявам летящи_обекти: Vecдин Лети> = vec![&птица, &самолет];

за обект в летящи_обекти {
object.fly();
}
}

The основен функцията инстанцира Самолет и птица видове. The летящи_обекти вектор е вектор на екземплярите на обекта, а за цикъл преминава през вектора и извиква летя метод на случаите.

Внедряване на полиморфизъм в Rust

Клас или тип е полиморфен, ако множество типове представляват интерфейс. Тъй като характеристиките осигуряват функционалността за дефиниране на поведение в Rust, като същевременно осигуряват общ интерфейс за писане на общ код, можете да използвате характеристиките за внедряване на полиморфизъм.

Ето една черта с име Възможност за рисуване който определя поведението за изобразяване на обекти на екрана:

Характерна чертаВъзможност за рисуване {
fnрисувам(&себе си);
}

Типовете, които имплементират характеристиката Drawable, имат достъп до рисувам функция.

структураПравоъгълник {
ширина: u32,
височина: u32,
}

импл Възможност за рисуване за правоъгълник {
fnрисувам(&себе си) {
// Изобразяване на правоъгълника на екрана
}
}

Можете да напишете общ код, който чертае обекти, които изпълняват Възможност за рисуване Характерна черта.

fnчертеж_обект(обект: &T) {
object.draw();
}

The чертеж_обект функцията приема общ тип T като вход, който изпълнява Възможност за рисуване черта и нарича рисувам метод върху чертата. Различни обекти могат да реализират Възможност за рисуване черта и достъп до функционалността.

Внедряване на абстракция в Rust

Абстракцията е ООП концепция където класове и интерфейси са достъпни за определени обекти и типове. Можете да внедрите абстракция в Rust с характеристики.

Ето примерна черта за медиен плейър:

Характерна чертаМедия {
fnиграя(&себе си);
}

Структури и енуми, които изпълняват Медия чертата трябва да осигури изпълнение за играя метод.

структураПесен {
заглавие: низ,
художник: низ,
}

импл Медия за Песен {
fnиграя(&себе си) {
println!(„Възпроизвежда се песен: {} от {}“, себе си.заглавие, себе си.художник);
}
}

The Песен struct изпълнява Медия черта чрез осигуряване на изпълнение за играя метод, който отпечатва съобщение с полетата на Песен структури към конзолата.

fnосновен() {
// Създаване на екземпляр на структурата Song
позволявам песен = Песен {
заглавие: низ::от("Бохемска рапсодия"),
художник: низ::от("кралица"),
};

// Извикване на метода за възпроизвеждане на екземпляра на песента
song.play();
}

The песен променливата е екземпляр на Песен struct и променливата може да осъществява достъп и да извиква играя метод.

Организирането на Rust Code е лесно

Обектно-ориентираното програмиране помага при организацията на кода. Благодарение на модулната система на Rust можете лесно да организирате вашия Rust код, като същевременно внедрявате OOP концепциите за вашето приложение, за да поддържате кода си организиран, управляем и интуитивен.