In Rust beheren zichtbaarheid modifiers de toegang tot module-elementen (structuren, functies, constanten, enz.). Standaard is alles wat in een module wordt gedeclareerd privé (alleen toegankelijk in die module). Er zijn speciale modifiers:
pub: maakt het element openbaar (zichtbaar vanuit elke externe module).pub(crate): zichtbaarheid is beperkt tot de huidige crate (pakket).pub(super): zichtbaarheid is beperkt tot de bovenliggende module.pub(in path): zichtbaarheid is beperkt tot een bepaalde pad.Voorbeeld:
mod foo { pub struct Bar { pub x: i32, // veld is overal toegankelijk y: i32, // veld is privé } pub(crate) fn crate_fn() {} pub(super) fn super_fn() {} fn private_fn() {} }
Het belangrijkste verschil met bijvoorbeeld C++ of Java is dat er geen apart niveau voor protected is, en de toegankelijkheid streng wordt gecontroleerd op module/pad-niveau, niet op klassenhiërarchie.
Vraag: Als een structuur wordt gedeclareerd als pub struct Foo, zullen de privé velden ervan toegankelijk zijn in een andere module van hetzelfde project?
Vaak antwoorden: Ja, want de structuur is openbaar.
Juiste antwoord: Nee, alleen de structuur zelf (Foo) wordt zichtbaar, en haar velden alleen als die velden ook met de modifier pub zijn gedeclareerd. Velden zonder pub blijven privé, zelfs als de structuur zelf openbaar is.
Voorbeeld:
mod foo { pub struct Bar { pub x: i32, y: i32, } } fn main() { let bar = foo::Bar { x: 1, y: 2 }; // Fout: veld `y` is niet toegankelijk }
Verhaal
In een groot project werd een structuur openbaar geëxporteerd via pub, maar de velden werden standaard privé gemaakt. Andere modules konden geen instanties van de structuur direct maken, en de enige oplossing was het schrijven van extra constructors of het verklaren van de benodigde velden als pub. Dit leidde tot een falen van de API totdat deze grondig was herzien.
Verhaal
Een van de ontwikkelaars in de bibliotheek gebruikte alleen pub(crate) voor functies, in de veronderstelling dat deze zouden worden aangeroepen vanuit binaire projecten die deze bibliotheek gebruikten. Echter, dergelijke functies werden onbereikbaar in een externe binaire crate, wat problemen veroorzaakte bij de integratie.
Verhaal
In een van de plugins voor de API-server werden pub(super) gebruikt voor structuren, maar na verloop van tijd ontstond de behoefte aan toegang tot hen vanuit andere modules; door de configuratie van de zichtbaarheid was het noodzakelijk om op verschillende plaatsen modules ingrijpend te herschrijven om de vereiste zichtbaarheid te waarborgen zonder de encapsulatie te schenden.