Historique de la question :
Dans des langages comme C++ ou Java, les modificateurs d'accès (public, private, protected) assurent la visibilité des membres de la classe, mais de manière assez flexible — souvent sans empêcher une utilisation erronée de l'API. En Rust, dès ses premières versions, un système de contrôle d'accès stricte et explicitement modulaire a été mis en place pour limiter les "fuites" de détails internes vers l'extérieur.
Problème :
Il est souvent nécessaire de cacher partiellement une structure du code externe : par exemple, les champs sont privés, tandis que seules les méthodes sont exposées. Si l'accès n'est pas restreint, il est possible de compromettre involontairement les invariants de la structure (par exemple, en exposant directement un Vec interne). Publier une structure sans réflexion rend l'API fragile.
Solution :
En Rust, tout est privé par défaut. Le mot-clé pub est utilisé pour l'exportation explicite : pour les structures, on peut déclarer la structure elle-même comme visible, tandis que les champs peuvent rester cachés. Les méthodes peuvent être déclarées pub ou privées individuellement. De plus, des formes non standards telles que pub(crate) ou pub(super) permettent de configurer finement le niveau d'accès.
Exemple de code :
mod domain { pub struct User { pub name: String, age: u32, // champ privé } 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 — erreur d'accès ! champ fermé en dehors du module }
Caractéristiques clés :
Peut-on rendre une structure pub, mais garder tous ses champs privés ? Comment alors créer ses instances en dehors du module ?
Oui. C'est ce que l'on fait généralement : structure pub, champs privés, création uniquement via des constructeurs publics (par exemple, pub fn new...).
Un champ de structure sera-t-il visible dans le code externe lors de la déclaration pub struct Foo ?
Non, par défaut chaque champ reste privé — il faut spécifiquement indiquer pub pour le champ. pub struct rend uniquement le type visible.
Le pub fonctionne-t-il de la même manière pour les enum ?
Pour enum, pub s'applique à toutes les variantes, mais pour les données associées dans les variantes (par exemple, champ à l'intérieur de Variant(value: T)), il faut aussi indiquer pub si vous voulez rendre les détails accessibles.
Dans la bibliothèque, la structure était déclarée comme pub struct Config, tous les champs étaient aussi pub — pour que l'utilisateur puisse les "voir". En conséquence, tout code externe pouvait changer arbitrairement l'état, violer les invariants, provoquant des panic de manière inattendue.
Avantages :
Inconvénients :
Structure Config pub, tous les champs privés. Pour la configuration — uniquement via des méthodes de builder, un constructeur par défaut ou des fonctions setter/getter. En dehors du module, il est impossible de briser les invariants.
Avantages :
Inconvénients :