Geschichte der Frage:
In Sprachen wie C++ oder Java gewährleisten Zugriffsmodifikatoren (public, private, protected) die Sichtbarkeit von Klassenmitgliedern, jedoch sehr flexibel — und oft verhindern sie nicht die fehlerhafte Nutzung von APIs. In Rust wurde ab den frühen Versionen ein strenges, deutlich modulares Zugriffssteuerungssystem eingeführt, um das "Durchsickern" interner Details nach außen zu begrenzen.
Problem:
Eine Struktur muss oft teilweise vor externem Code verborgen bleiben: zum Beispiel sind Felder privat, und nur Methoden werden nach außen exponiert. Wenn der Zugriff nicht eingeschränkt wird, kann man unbeabsichtigt die Invarianten der Struktur verletzen (zum Beispiel, indem man direkt einen internen Vec exponiert). Eine unüberlegte Veröffentlichung von Strukturen macht die API anfällig.
Lösung:
In Rust ist alles standardmäßig privat. Das Schlüsselwort pub wird verwendet, um explizit zu exportieren: Bei Strukturen kann man die Struktur selbst sichtbar machen und die Felder verborgen halten. Methoden werden individuell als pub oder privat deklariert. Darüber hinaus ermöglichen nicht-standardisierte Formen wie pub(crate) oder pub(super) eine feine Abstimmung des Zugriffs.
Codebeispiel:
mod domain { pub struct User { pub name: String, age: u32, // privates Feld } impl User { pub fn new(name: String, age: u32) -> Self { Self { name, age } } pub fn age(&self) -> u32 { self.age } } } use domain::User; fn main() { let u = User::new("Eve".to_string(), 24); println!("{} {}", u.name, u.age()); // u.age — Zugriffsfehler! Feld ist außerhalb des Moduls geschlossen }
Wichtige Merkmale:
Kann man eine Struktur pub machen, aber alle ihre Felder privat lassen? Wie kann man dann Instanzen außerhalb des Moduls erstellen?
Ja. So wird es normalerweise gemacht: Struktur ist pub, Felder sind privat, Erstellung nur über öffentliche Konstruktoren (zum Beispiel pub fn new...).
Wird ein Feld der Struktur sichtbar im externen Code, wenn man pub struct Foo deklariert?
Nein, standardmäßig bleibt jedes Feld weiterhin privat — man muss ausdrücklich pub für das Feld angeben. pub struct macht nur den Typ sichtbar.
Funktioniert pub für enum auch so?
Bei enum wird pub auf alle Varianten angewendet, aber für assoziierte Daten in Varianten (zum Beispiel, Feld innerhalb von Variant(value: T)) muss man ebenfalls explizit pub angeben, wenn man die Inneren zugänglich machen möchte.
In einer Bibliothek wurde eine Struktur als pub struct Config deklariert, alle Felder waren ebenfalls pub — damit der Benutzer sie "sehen" konnte. Infolgedessen konnte jeder externe Code den Zustand beliebig ändern, Invarianten verletzen und ohne Grund einen Panic auslösen.
Vorteile:
Nachteile:
Die Struktur Config ist pub, alle Felder sind privat. Für die Konfiguration — nur über Builder-Methoden, Standardkonstruktor oder Setter/Getter-Funktionen. Außerhalb des Moduls können Invarianten nicht verletzt werden.
Vorteile:
Nachteile: