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
selfkeyword is used to refer the same module, while thesuperkeyword is used to refer parent module. Also, thesuperkeyword 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()tophrasesmodule by re-exportinghellotophrasesmodule. 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.