Das Public-Schlüsselwort
Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 9 von 61.
In der vorherigen Lektion haben Sie gelernt, wie man Code in separaten Moduldateien organisiert. Wenn Sie jedoch versuchen würden, das Player-Struct aus main.rs zu verwenden, würden Sie auf einen Compiler-Fehler stoßen. Das liegt daran, dass in einem Rust-Modul alles standardmäßig privat ist.
Um Elemente von außerhalb ihres Moduls zugänglich zu machen, müssen Sie diese explizit mit dem Schlüsselwort pub kennzeichnen:
// player.rs
pub struct Player {
pub name: String,
pub score: u32,
}
impl Player {
pub fn new(name: String) -> Player {
Player { name, score: 0 }
}
}
Beachten Sie, wie pub an mehreren Stellen erscheint – an der Struct selbst, an jedem Feld und an der Methode. Jedes Element benötigt seine eigene Sichtbarkeitsdeklaration.
Ohne pub am struct können andere Dateien den Typ nicht einmal benennen. Ohne pub an Feldern können sie nicht direkt auf die Daten zugreifen. Ohne pub an Methoden können sie diese nicht aufrufen.
Jetzt können Sie in main.rs die öffentlichen Elemente des Moduls verwenden:
// main.rs
mod player;
use player::Player;
fn main() {
let p = Player::new(String::from("Alice"));
println!("{}", p.name);
}
Die use-Anweisung bringt Player in den Gültigkeitsbereich, sodass Sie nicht jedes Mal player::Player schreiben müssen. Dieser Privacy-by-Default-Ansatz ist beabsichtigt – er ermutigt Sie dazu, sorgfältig darüber nachzudenken, welche Teile Ihres Codes nach außen hin offengelegt werden sollten.
Aufgabe
EinfachLassen Sie uns einen einfachen Produktkatalog erstellen, indem wir Ihren Code auf zwei Dateien aufteilen und die richtigen Elemente öffentlich machen, damit sie von Ihrem Hauptprogramm aus verwendet werden können.
Sie werden zwei Dateien erstellen:
product.rs: Definieren Sie eineProduct-Struktur mit zwei Feldern:name(String) undprice(f64). Fügen Sie eine assoziierte Funktion namensnewhinzu, die einen Namen und einen Preis entgegennimmt und ein neuesProductzurückgibt. Denken Sie daran, die Struktur, ihre Felder und die Methode als öffentlich zu markieren, damit von außerhalb des Moduls auf sie zugegriffen werden kann.main.rs: Deklarieren Sie das Produkt-Modul, bringen SieProductmit eineruse-Anweisung in den Gültigkeitsbereich, erstellen Sie dann ein Produkt und geben Sie dessen Details aus.
Überlegen Sie genau, wo Sie das Schlüsselwort pub benötigen – die Struktur selbst muss sichtbar sein, die Felder müssen zum Lesen zugänglich sein und die Konstruktor-Methode muss von main.rs aus aufrufbar sein.
Ihre Ausgabe sollte genau diesem Format folgen:
Product: {name}, Price: ${price}Wenn Sie beispielsweise ein Produkt mit dem Namen "Laptop" und dem Preis 999.99 erstellen, lautet die Ausgabe:
Product: Laptop, Price: $999.99Sie erhalten zwei Eingaben: den Produktnamen und den Preis.
Spickzettel
In Rust ist standardmäßig alles in einem Modul privat. Um Elemente von außerhalb ihres Moduls zugänglich zu machen, verwenden Sie das Schlüsselwort pub.
Markieren Sie Structs, Felder und Methoden als öffentlich:
// player.rs
pub struct Player {
pub name: String,
pub score: u32,
}
impl Player {
pub fn new(name: String) -> Player {
Player { name, score: 0 }
}
}
Jedes Element benötigt seine eigene Sichtbarkeitsdeklaration:
pubbeim Struct macht den Typ sichtbarpubbei Feldern ermöglicht den direkten Zugriff auf Datenpubbei Methoden ermöglicht deren Aufruf
Verwenden Sie die use-Anweisung, um Elemente in den Gültigkeitsbereich (Scope) zu bringen:
// main.rs
mod player;
use player::Player;
fn main() {
let p = Player::new(String::from("Alice"));
println!("{}", p.name);
}
Probier es selbst
// Deklariere das Modul product
mod product;
// TODO: Bringe Product mit einer use-Anweisung in den Gültigkeitsbereich
fn main() {
// Eingabe lesen
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut price_input = String::new();
std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
let price: f64 = price_input.trim().parse().expect("Failed to parse price");
// TODO: Erstelle ein neues Product mit der Funktion Product::new
// TODO: Gib die Produktdetails in folgendem Format aus:
// Product: {name}, Price: ${price}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Methoden und Verhalten
Einführung in ImplementierungsblöckeDer Self-ParameterVeränderliche MethodenAssoziierte FunktionenMehrere ImplementierungsblöckeMethod ChainingRückblick – Rechteck-Aktionen4Projekt: Virtuelles Haustier
Das Haustier definierenDas Haustier füttern7Standard-Traits
Das Debug-TraitDas Display-TraitClone und CopyGleichheits-TraitsZusammenfassung – Druckbarer Punkt10Projekt: Dokumentensystem
Das Draw-TraitText-Komponente2Kapselung und Module
Grundlagen der ModuleDas Public-SchlüsselwortPrivate FelderGetterSetterWiederholung – Sicherer Tresor5Generics
Generische StructsGenerische MethodenMehrere generische TypenGenerische FunktionenZusammenfassung - Koordinatenpunkt8Traits als Einschränkungen
Syntax für Trait BoundsMehrfache BoundsDie Where-KlauselTypen mit Traits zurückgebenRückblick – Generischer Drucker11Design Patterns in Rust
Newtype-PatternKompositionDas Drop-TraitFrom und IntoZusammenfassung – Smart Pointer Mock3Fortgeschrittene Enums
Enums mit DatenMethoden für EnumsMatching von DatenvariantenDas Option-Enum erneut betrachtetZusammenfassung – Shape-Enum6Definition von Traits
Was ist ein Trait?Traits implementierenStandardimplementierungenStandardimplementierungen überschreibenTraits mit ParameternZusammenfassung – Media Player