«Pub» est-il censé indiquer public-to-crate ou public-to-module? [dupliquer]
Pour rendre publiques les méthodes d'un sous-module, vous devez les réexporter explicitement ou bien rendre le sous-module lui-même public:
mod foo {
mod bar {
pub fn baz() {}
}
pub use self::bar::baz;
}
Cela semble indiquer qu'il pub
est utilisé pour indiquer qu'une chose doit être publique uniquement pour un module (puisque vous pouvez choisir de ne pas le faire)
Mais si vous utilisez un type privé défini dans le contexte externe, vous obtenez une erreur si vous essayez de rendre publique une fonction publique l'impliquant dans le contexte interne, même si elle n'est pas réexportée.
mod foo {
struct Foo;
mod bar {
use super::Foo;
pub fn baz(foo: Foo) {}
}
}
résulte en
error[E0446]: private type `Foo` in public interface
--> src/lib.rs:7:9
|
2 | struct Foo;
| - `Foo` declared as private
...
7 | pub fn baz(foo: Foo) {}
| ^^^^^^^^^^^^^^^^^^^^ can't leak private type
Quelle est la manière idiomatique d'utiliser le pub
mot-clé? Doit-il être réservé aux choses qui sont réellement publiques ou peut-il être utilisé pour des modules internes?
Réponses
La raison pour laquelle votre exemple ne parvient pas à se compiler est finalement parce que la RFC (136) l'a dit. (Voir aussi le numéro 22261 )
Quelles restrictions s'appliquent aux objets publics?
Les règles applicables aux différents types d'objets publics sont les suivantes:
- S'il s'agit d'une
static
déclaration, les éléments mentionnés dans son type doivent être publics.- S'il s'agit d'une
fn
déclaration, les éléments auxquels il est fait référence dans ses limites de trait, ses types d'argument et son type de retour doivent être publics.- S'il s'agit d'une déclaration
struct
ouenum
, les éléments auxquels il est fait référence dans ses limites de trait et dans les types de sespub
champs doivent être publics.- S'il s'agit d'une
type
déclaration, les éléments visés dans sa définition doivent être publics.- S'il s'agit d'une
trait
déclaration, les items référencés dans ses super-traits, dans les limites de ses paramètres de type et dans les signatures de ses méthodes (voirfn
cas ci-dessus) doivent être publics.
En bref, il baz
n'est pas permis d'être pub
car il a un argument qui est un type privé. Ainsi, si baz
c'est le cas, pub
cela permettrait au parent mod foo
de réexporter baz
en faisant pub use bar::baz;
. Ceci n'est bien sûr pas autorisé, et c'est la raison pour laquelle l'exemple dans son ensemble est illégal.
Certains ont précédemment mentionné que cela pub fn baz
devrait être autorisé, et à la place de donner une erreur de compilation dans le cas où le module parent le réexporte. Cependant, cela nécessiterait une analyse statique plus complexe pour détecter, et n'a finalement pas été fait parce que la RFC a défini qu'il est illégal.
pub
spécifie que l'élément est accessible par le module parent. Si tous les ancêtres du module le sont pub
, alors cet élément est exporté par la caisse dans son ensemble.
Le mot-clé
pub
rend tout module, fonction ou structure de données accessible depuis l'intérieur des modules externes. Lepub
mot clé peut également être utilisé dans uneuse
déclaration pour réexporter un identifiant à partir d'un espace de noms.- Documentation sur la rouille
Avec la notion d'élément public ou privé, Rust autorise les accès aux éléments dans deux cas:
- Si un élément est public, alors il peut être accédé en externe à partir d'un module m si vous pouvez accéder à tous les modules ancêtres de l'élément à partir de m. Vous pouvez également potentiellement nommer l'élément via des réexportations. Voir ci-dessous.
- Si un élément est privé, il est accessible par le module actuel et ses descendants.
- The Rust Reference - Visibilité et confidentialité