Achtergrond:
In talen zoals C++ of Java zorgen toegangsmodifiers (public, private, protected) voor de zichtbaarheid van de leden van de klasse, maar zijn vrij flexibel — en voorkomen vaak niet onbedoeld gebruik van de API. In Rust, vanaf de vroege versies, is het toegangssysteem streng en expliciet modulair gemaakt om "lekken" van interne details naar buiten te beperken.
Probleem:
Structuren moeten vaak gedeeltelijk verborgen worden voor externe code: bijvoorbeeld, velden zijn privé, en alleen methoden worden naar buiten gebracht. Als de toegang niet wordt beperkt, kunnen de invarianten van de structuur per ongeluk worden aangetast (bijvoorbeeld door een interne Vec direct toegankelijk te maken). Een ondoordachte publicatie van de structuur maakt de API kwetsbaar.
Oplossing:
In Rust is alles standaard privé. Het sleutelwoord pub wordt gebruikt voor expliciete export: gestructureerde kunnen afzonderlijk openbaar worden gemaakt, terwijl de velden verborgen blijven. Methoden worden individueel als pub of privé gedeclareerd. Bovendien bieden niet-standaard vormen zoals pub(crate) of pub(super) de mogelijkheid om het toegangsniveau fijn af te stemmen.
Voorbeeldcode:
mod domain { pub struct User { pub name: String, age: u32, // privé veld } 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 — toegangsfout! veld is gesloten buiten de module }
Belangrijkste kenmerken:
Kun je een structuur pub maken, maar alle velden privé laten? Hoe maak je dan instanties ervan buiten de module?
Ja. Dat is gebruikelijk: structuur pub, velden privé, creatie alleen via publieke constructors (bijvoorbeeld, pub fn new...).
Wordt een veld van de structuur zichtbaar in externe code bij de declaratie pub struct Foo?
Nee, standaard is elk veld nog steeds privé — je moet pub expliciet voor het veld aangeven. pub struct maakt alleen het type zichtbaar.
Werkt pub ook voor enums?
Voor enums is pub van toepassing op alle varianten, maar voor geassocieerde gegevens in de varianten (bijvoorbeeld, veld binnen Variant(value: T)) moet je nog steeds expliciet pub aangeven als je de interne details toegankelijk wilt maken.
In de bibliotheek was de structuur gedeclareerd als pub struct Config, alle velden ook pub — zodat de gebruiker ze "zou zien". Hierdoor kon elke externe code willekeurig de staat wijzigen, invarianten schenden, en panics veroorzaken uit het niets.
Voordelen:
Nadelen:
Structuur Config pub, alle velden privé. Voor configuratie — alleen via builder-methoden, default-constructor of setter/getter-functies. Buiten de module kunnen invarianten niet worden gebroken.
Voordelen:
Nadelen: