I am a newbie in Rust and just started to read the programming book while doing rustling
exercises. In the modules2.rs
exercise, I am confused why the following code compiles:
mod delicious_snacks {
pub use self::fruits::PEAR as fruit;
pub use self::veggies::CUCUMBER as veggie;
mod fruits {
pub const PEAR: &'static str = "Pear";
pub const APPLE: &'static str = "Apple";
}
mod veggies {
pub const CUCUMBER: &'static str = "Cucumber";
pub const CARROT: &'static str = "Carrot";
}
}
fn main() {
println!(
"favorite snacks: {} and {}",
delicious_snacks::fruit,
delicious_snacks::veggie
);
}
Specifically, I am wondering why it is OK for main
to access private fruits
and veggies
modules just because their use
s are marked pub
? On the other hand, if we don't use pub use
, then, without making fruits
and veggies
pub
, one cannot access e.g., delicious_snacks::fruits::PEAR
in main
because fruits
is not public. Similarly, if we don't use pub
for const PEAR
, even with pub use self::fruits::PEAR as fruit
, we still cannot compile delicious_snacks::fruit
. So what exactly is the rule here? Why is it OK to not mark pub
for those modules?
The constants PEAR/APPLE/CUCUMBER/CARROT
are marked as pub
, which means they can be accessed from everywhere, even if they're in a private module.
This is a common technique, to implement something in a private module, and re-export only the things we want, e.g.
// actual implementation is here
mod foo_internal;
pub use foo_internal::{Foo, Bar};
This still maintains privacy/visibility, since Foo
and Bar
can't be re-exported if they're private.
You can also create a new module hierarchy for users of your library:
mod foo_internal;
pub mod foo {
pub use foo_internal::Foo;
}
pub mod bar {
pub use foo_internal::Bar;
}
This clearly separates the public interface from implementation details, so the implementation can be freely refactored without changing the public modules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With