Dans Rust, les modificateurs de visibilité contrôlent l'accès aux éléments des modules (structures, fonctions, constantes, etc.). Par défaut, tout ce qui est déclaré dans un module est privé (accessible uniquement dans ce module). Il existe des modificateurs spéciaux :
pub : rend l'élément accessible publiquement (visible depuis n'importe quel module externe).pub(crate) : la visibilité est limitée au crate (paquet) actuel.pub(super) : la visibilité est limitée au module parent.pub(in path) : la visibilité est limitée à un chemin spécifique.Exemple :
mod foo { pub struct Bar { pub x: i32, // champ accessible partout y: i32, // champ privé } pub(crate) fn crate_fn() {} pub(super) fn super_fn() {} fn private_fn() {} }
La principale différence par rapport à, par exemple, C++ ou Java, est qu'il n'y a pas de niveau distinct pour « protected », et que l'accessibilité est strictement contrôlée au niveau des modules/chemins, plutôt qu'à travers la hiérarchie des classes.
Question : Si une structure est déclarée comme pub struct Foo, ses champs privés seront-ils accessibles dans un autre module du même projet ?
Réponse fréquente : Oui, car la structure est publique.
Réponse correcte : Non, seule la structure elle-même (Foo) deviendra visible, et ses champs ne le seront que s'ils sont également déclarés avec le modificateur pub. Les champs sans pub restent privés, même si la structure elle-même est publique.
Exemple :
mod foo { pub struct Bar { pub x: i32, y: i32, } } fn main() { let bar = foo::Bar { x: 1, y: 2 }; // Erreur : champ `y` inaccessible }
Histoire
Dans un grand projet, on a publiquement exporté une structure via pub, mais les champs ont été laissés privés par défaut. D'autres modules ne pouvaient pas créer d'instances de la structure directement, et la seule solution était d'écrire des constructeurs supplémentaires ou de déclarer les champs nécessaires comme pub. Cela a conduit à un échec de l'API jusqu'à sa révision finale.
Histoire
Un des développeurs d'une bibliothèque a utilisé uniquement pub(crate) pour les fonctions, présumant qu'elles pouvaient être appelées depuis des projets binaires utilisant cette bibliothèque. Cependant, ces fonctions sont devenues inaccessibles dans un crate binaire externe, ce qui a causé des problèmes d'intégration.
Histoire
Dans un des plugins pour serveurs API, pub(super) a été utilisé pour des structures, mais après un certain temps, il est devenu nécessaire d'y accéder depuis d'autres modules ; à cause de la configuration de la visibilité, il a fallu réécrire radicalement plusieurs modules pour assurer la portée nécessaire sans compromettre l'encapsulation.