-
When I first started with Rust, I tended to just use
pub mod
everywhere as it was "easier" -
I'm now shifting to a style where I use
mod
everywhere, withpub use
for anything I need to export. -
I don't know if this is the right style (or if I'm going overboard). Is there a number of "standard mod vs pub mod" styles I can pick from?
"style" is really just whatever you want it to be, or, even better, whatever is the best.
Here are some examples for either:
-
pub mod
:- When you want to distinguish between
self
(In module terms) andmy_module
,
- When you want to distinguish between
pub mod has_derived_a {
struct DerivedA;
impl super::Trait for DerivedA {}
//Some more items relating to `a`
}
pub mod has_derived_b {
struct DerivedB;
impl super::Trait for DerivedB {}
//Some more items
}
pub trait Trait {}
-
pub use
:- When you want to use
my_module
's members as my own, but have them in a separate file - When you want to rename a member:
- When you want to use
mod foo {
struct Bar<T> {z: PhantomData<T>}
}
pub use foo::Bar as Cont;
I strongly believe that pub mod
is overrused. By keeping most modules private and using pub use
to expose a flatter heirarchy (a.k.a. the facade pattern), you:
- Make the public API easier to learn and use.
- Make it easier to move things to other places while refactoring without breaking the public API.
Some people look at std
and see how nested its public API is and think that's how their crate should look. But std
is different. std
has the scope of fifty crates. (and in fact it still makes plenty of use of the facade pattern; the public module tree you see is only the tip of the iceburg!)
That said, sometimes a pub
mod is useful as a documentation page. The way it's used for disambiguation in crates like bzip2
is also reasonable.
I also like to have a pub mod
for a collection so it can contain types with general names like IntoIter
.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.