01. In the same file
Related code and data are grouped into a module and stored in the same file.
fn main() {
greetings::hello();
}
mod greetings {
// ⭐️ By default, everything inside a module is private
pub fn hello() { // ⭐️ So function has to be public to access from outside
println!("Hello, world!");
}
}
Modules can also be nested.
fn main() {
phrases::greetings::hello();
}
mod phrases {
pub mod greetings {
pub fn hello() {
println!("Hello, world!");
}
}
}
Private functions can be called from the same module or from a child module.
// 01. Calling private functions of the same module
fn main() {
phrases::greet();
}
mod phrases {
pub fn greet() {
hello(); // Or `self::hello();`
}
fn hello() {
println!("Hello, world!");
}
}
// 02. Calling private functions of the parent module
fn main() {
phrases::greetings::hello();
}
mod phrases {
fn private_fn() {
println!("Hello, world!");
}
pub mod greetings {
pub fn hello() {
super::private_fn();
}
}
}
💡 The
self
keyword is used to refer the same module, while thesuper
keyword is used to refer parent module. Also, thesuper
keyword can be used to access root functions from inside a module.
fn main() {
greetings::hello();
}
fn hello() {
println!("Hello, world!");
}
mod greetings {
pub fn hello() {
super::hello();
}
}
🔎 When writing tests it’s a good practice to write tests inside a test module because they compile only when running tests.
fn greet() -> String {
"Hello, world!".to_string()
}
#[cfg(test)] // Only compiles when running tests
mod tests {
use super::greet; // Import root greet function
#[test]
fn test_greet() {
assert_eq!("Hello, world!", greet());
}
}
02. In a different file, same directory
// ↳ main.rs
mod greetings; // Import greetings module
fn main() {
greetings::hello();
}
// ↳ greetings.rs
// ⭐️ No need to wrap the code with a mod declaration. The file itself acts as a module.
pub fn hello() { // The function has to be public to access from outside
println!("Hello, world!");
}
If we wrap file content with a mod
declaration, it will act as a nested module.
// ↳ main.rs
mod phrases;
fn main() {
phrases::greetings::hello();
}
// ↳ phrases.rs
pub mod greetings { // ⭐️ The module has to be public to access from outside
pub fn hello() {
println!("Hello, world!");
}
}
03. In a different file, different directory
mod.rs
in the directory module root is the entry point to the directory module. All other files in that directory root, act as sub-modules of the directory module.
// ↳ main.rs
mod greetings;
fn main() {
greetings::hello();
}
// ↳ greetings/mod.rs
pub fn hello() { // ⭐️ The function has to be public to access from outside
println!("Hello, world!");
}
Again, If we wrap file content with a mod
declaration, it will act as a nested module.
// ↳ main.rs
mod phrases;
fn main() {
phrases::greetings::hello();
}
// ↳ phrases/mod.rs
pub mod greetings { // ⭐️ The module has to be public to access from outside
pub fn hello() {
println!("Hello, world!");
}
}
Other files in the directory module act as sub-modules for mod.rs
.
// ↳ main.rs
mod phrases;
fn main() {
phrases::hello()
}
// ↳ phrases/mod.rs
mod greetings;
pub fn hello() {
greetings::hello()
}
// ↳ phrases/greetings.rs
pub fn hello() {
println!("Hello, world!");
}
⭐️ If you need to access an element of phrases/greetings.rs
from outside the module, you have to import the greetings
module as a public module.
// ↳ main.rs
mod phrases;
fn main() {
phrases::greetings::hello();
}
// ↳ phrases/mod.rs
pub mod greetings; // ⭐️ `pub mod` instead `mod`
// ↳ phrases/greetings.rs
pub fn hello() {
println!("Hello, world!");
}
🔎 It’s unable to import child file modules of directory modules to
main.rs
, so you can’t usemod phrases::greetings;
frommain.rs
. But there is a way to importphrases::greetings::hello()
tophrases
module by re-exportinghello
tophrases
module. So you can call it directly asphrases::hello()
.
// ↳ phrases/greetings.rs
pub fn hello() {
println!("Hello, world!");
}
// ↳ phrases/mod.rs
pub mod greetings;
pub use self::greetings::hello; // Re-export `greetings::hello` to phrases
// ↳ main.rs
mod phrases;
fn main() {
phrases::hello(); // You can call `hello()` directly from phrases
}
This allows you to present an external interface that may not directly map to your internal code organization. If still it is not clear, don’t worry; We discuss the usages of use
on an upcoming section in this post.