Rust hat keine native Unterstützung für OOP, aber Sie können diese Techniken trotzdem verwenden, um das Paradigma zu nutzen.

Die objektorientierte Programmierung (OOP) vereinfacht das Softwaredesign, indem sie die Verwendung von Objekten zur Darstellung realer Entitäten und Konzepte betont. OOP fördert die Wartbarkeit durch Einkapseln von Funktionalität in Objekten.

Rust ist eine flexible Sprache, die funktionale und prozedurale Programmierung unterstützt. Obwohl es nativ keine objektorientierte Programmierung unterstützt, können Sie OOP-Konzepte mit den eingebauten Datentypen von Rust implementieren.

Kapselung in Rost

Bei der Kapselung wird Code in eigenständige Einheiten organisiert, die interne Details verbergen Bereitstellung einer öffentlichen Schnittstelle für externe Interaktion, um die Komplexität zu minimieren und den Code zu verbessern Wartbarkeit.

Sie können Rust-Code mit Modulen kapseln. Ein Modul ist eine Sammlung von Elementen, einschließlich Funktionen, Strukturen, Aufzählungen und Konstanten. Rust-Module bieten Funktionen zum Gruppieren und Definieren von Grenzen zwischen Teilen eines Programms.

instagram viewer

Verwenden von Modulen zum Kapseln von Daten und Funktionen

Sie können ein Modul mit definieren Mod Schlüsselwort gefolgt von einem Namen:

Mod mein_modul {
// Modulelemente kommen hierher
}

Sie können Module hierarchisch organisieren, indem Sie ihre Deklarationen verschachteln:

Mod parent_module {
Mod mein_modul {
// Modulelemente kommen hierher
}
}

Sie können dann auf verschachtelte Module mit der vollständigen Hierarchie verweisen, indem Sie jedes Modul mit einem doppelten Doppelpunkt trennen, z. B. parent_module:: mein_modul.

Standardmäßig sind Elemente innerhalb von Modulen privat und nur für Code innerhalb desselben Moduls zugänglich. Aber Sie können Module öffentlich machen, indem Sie die verwenden Kneipe Stichwort:

Mod mein_modul {
Kneipefnmeine_funktion() {
// Hier kommt der Funktionskörper
}
}

Sie können dann zugreifen meine_funktion aus anderen Teilen Ihres Programms.

Verwenden von Merkmalen zum Definieren von Verhaltensweisen

Eine weitere Möglichkeit, wie Rust die Kapselung ermöglicht, ist die Verwendung von Traits. Eigenschaften definieren Verhaltensweisen, die Typen implementieren können, und stellen sicher, dass verschiedene Typen derselben Schnittstelle entsprechen.

KneipeMerkmalDruckbar {
fndrucken(&selbst);
}

KneipeStrukturMein Typ {
// Felder hier strukturieren
}

impl Druckbar für Mein Typ {
fndrucken(&selbst) {
// Implementierung hier
}
}

Der Druckbar Eigenschaft hat a drucken Methode und die Mein Typ struct implementiert die Druckbar Merkmal durch die Implementierung der drucken Methode.

Mithilfe von Eigenschaften können Sie sicherstellen, dass jeder Typ, der die Druckbar Eigenschaft hat a drucken Methode. Dies ist praktisch, wenn Sie mit generischem Code arbeiten, der mit verschiedenen Typen zusammenarbeiten muss, die ein gemeinsames Verhalten aufweisen.

Erbe in Rust

Durch Vererbung können Sie eine Klasse basierend auf einer anderen definieren. Die Unterklasse erbt die Eigenschaften und Methoden ihrer Elternklasse.

In Rust werden Sie ermutigt, Komposition statt Vererbung zu verwenden. Komposition ist ein Prozess, bei dem neue Objekte durch Kombinieren vorhandener erstellt werden. Anstatt eine neue Klasse zu erstellen, die Funktionalität von der Basisklasse erbt, können Sie eine neue Struktur erstellen, die eine Instanz der Basisstruktur und ihrer Felder enthält.

Erstellen neuer Typen durch Kombinieren vorhandener Typen

Sie verwenden Aufzählungen und Strukturen, um neue Typen zu erstellen. Aufzählungen sind praktisch für Typen mit endlichen Werten, und Strukturen können mehrere Felder enthalten.

Sie können einen Aufzählungstyp für verschiedene Tierarten erstellen.

AufzählungTier {
Katze,
Hund,
Vogel,
// ...
}

Alternativ können Sie eine Struktur erstellen, die Felder für jeden Tiertyp enthält. Strukturen können Aufzählungen und andere Typen enthalten.

StrukturTier {
Name: Schnur,
Alter: u8,
animal_type: Tiertyp,
}

AufzählungTiertyp {
Katze,
Hund,
Vogel,
// ...
}

Der Tier struct enthält Werte von Tiertyp Aufzählungstyp.

Sie können Eigenschaften verwenden, um die Vererbung zu implementieren und einem Typ Verhalten hinzuzufügen, ohne einen neuen zu erstellen.

MerkmalFliege {
fnFliege(&selbst);
}

So können Sie die implementieren Fliege Merkmal für mehrere Arten.

StrukturVogel {
Name: Schnur,
Spannweite: f32,
}

impl Fliege für Vogel {
fnFliege(&selbst) {
drucken!("{} fliegt!", selbst.Name);
}
}

StrukturEbene {
Modell: Schnur,
Höchstgeschwindigkeit: u32,
}

impl Fliege für Ebene {
fnFliege(&selbst) {
drucken!("{} fliegt!", selbst.Modell);
}
}

Der Vogel Und Ebene Strukturen implementieren die Fliege trait und druckt Strings mit dem Drucken! Makro.

Sie können die anrufen Fliege -Methode für beide Strukturen, ohne ihre spezifischen Typen zu kennen.

fnhauptsächlich() {
lassen Vogel = Vogel {
Name: Schnur::aus("Adler"),
Spannweite: 2.0,
};

lassen Ebene = Ebene {
Modell: Schnur::aus("Boeing 747"),
Höchstgeschwindigkeit: 900,
};

lassen fliegende_objekte: Vekdyn Fliegen> = vec![&Vogel, &Flugzeug];

für Objekt In fliegende_objekte {
objekt.fly();
}
}

Der hauptsächlich Funktion instanziiert die Ebene Und Vogel Typen. Der fliegende_objekte vector ist ein Vektor der Objektinstanzen, und die für Schleife durchläuft den Vektor und ruft die auf Fliege Methode auf den Instanzen.

Implementierung von Polymorphismus in Rust

Eine Klasse oder ein Typ ist polymorph, wenn mehrere Typen eine Schnittstelle darstellen. Da Traits die Funktionalität zum Definieren von Verhaltensweisen in Rust bereitstellen und gleichzeitig eine gemeinsame Schnittstelle zum Schreiben von generischem Code bereitstellen, können Sie Traits verwenden, um Polymorphismus zu implementieren.

Hier ist eine Eigenschaft benannt Ziehbar die das Verhalten beim Rendern von Objekten auf dem Bildschirm definiert:

MerkmalZiehbar {
fnziehen(&selbst);
}

Typen, die das Drawable-Merkmal implementieren, können auf die zugreifen ziehen Funktion.

StrukturRechteck {
Breite: u32,
Höhe: u32,
}

impl Ziehbar für Rechteck {
fnziehen(&selbst) {
// Rendern Sie das Rechteck auf dem Bildschirm
}
}

Sie können generischen Code schreiben, der Objekte zeichnet, die die implementieren Ziehbar Merkmal.

fndraw_object(Objekt: &T) {
objekt.draw();
}

Der draw_object Die Funktion nimmt einen generischen Typ an T als Eingabe, die die implementiert Ziehbar Merkmal und ruft die ziehen Methode auf das Merkmal. Verschiedene Objekte können die implementieren Ziehbar trait und greifen Sie auf die Funktionalität zu.

Implementierung von Abstraktion in Rust

Abstraktion ist ein OOP-Konzept wobei Klassen und Schnittstellen für bestimmte Objekte und Typen zugänglich sind. Sie können Abstraktion in Rust mit Traits implementieren.

Hier ist ein Beispielmerkmal für einen Mediaplayer:

MerkmalMedien {
fnspielen(&selbst);
}

Strukturen und Aufzählungen, die die implementieren Medien trait muss eine Implementierung für die bereitstellen spielen Methode.

StrukturLied {
Titel: Schnur,
Künstler: Schnur,
}

impl Medien für Lied {
fnspielen(&selbst) {
drucken!(„Lied wird gespielt: {} von {}“, selbst.Titel, selbst.Künstler);
}
}

Der Lied struct implementiert die Medien -Eigenschaft, indem eine Implementierung für die bereitgestellt wird spielen Methode, die eine Nachricht mit den Feldern der ausgibt Lied Strukturen an die Konsole.

fnhauptsächlich() {
// Erstellen Sie eine Instanz der Song-Struktur
lassen Lied = Lied {
Titel: Schnur::aus("Bohemian Rhapsody"),
Künstler: Schnur::aus("Königin"),
};

// Aufruf der Play-Methode für die Song-Instanz
song.play();
}

Der Lied Variable ist eine Instanz von Lied struct, und die Variable kann auf die zugreifen und sie aufrufen spielen Methode.

Das Organisieren von Rust Code ist einfach

Die objektorientierte Programmierung hilft bei der Codeorganisation. Dank des Modulsystems von Rust können Sie Ihren Rust-Code einfach organisieren und gleichzeitig die OOP-Konzepte für Ihre Anwendung implementieren, um Ihren Code organisiert, überschaubar und intuitiv zu halten.