Absolute Path: The path starting from crate root. For code from an external crate, the path begins with the crate name. For code from the current crate, it starts with the literal crate
Relative Path: Starts from the current module and uses self
, super
, or an identifier in the current module
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order();
}
fn cook_order() {}
}
By default all child modules are private (Parent module cannot see anything in child)
On the other hand the child module can see everything in the parent module
crate modules
├── mod back_of_house: pub(crate)
│ ├── fn cook_order: pub(self)
│ └── fn fix_incorrect_order: pub(self)
└── fn deliver_order: pub(crate)
Using super
we can reference the items from parent module of the current module
mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("Peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
let mut meal = back_of_house::Breakfast::summer("Rye");
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
}
Even if an Struct is made public the fields in it are private. Each field needs to be explicitly made public (if it needs to be modified)
crate modules
├── mod back_of_house: pub(crate)
│ └── struct Breakfast: pub
└── fn eat_at_restaurant: pub
Enable Structs once an Enum is made public its variants automatically become public
mod back_of_house {
pub enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
let order1 = back_of_house::Appetizer::Soup;
let order2 = back_of_house::Appetizer::Salad;
}
Bringing Modules into Scope
The use
keyword is used to bring modules into scope (Similar to import statements in other languages). Once a module is brought into scope the entire path to items in that module don’t have to be used.
crate modules
├── fn eat_at_restaurant: pub
└── mod front_of_house: pub(crate)
└── mod hosting: pub
└── fn add_to_waitlist: pub
When using a function it is idiomatic in Rust to bring the parent module into scope
On the other hand, when bringing in structs, Enums, and other items with use
, it’s idiomatic to specify the full path
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
Special words used with use
crate
: Refers to current Rust projectself
: Refers to current modulesuper
: Parent module of the current module we are inside
If eat_at_restaurant
function is moved inside a module the use
statement would stop working
use
only creates the shortcut for the scope in which the use
occurs
When a module is brought into scope using use
keyword, the new name available is private
External code will not be able to use this new namespace
To make the namespace accessible from external code we can re-export the namespace using the pub use
keyword
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
// --snip--
}
fn function2() -> IoResult<()> {
// --snip--
}
Bringing Nested Paths into Scope
use std::cmp::Ordering;
use std::io;
// Recommended
use std::{cmp::Ordering, io};
use std::io;
use std::io::Write;
// Recommended
use std::io::{self, Write};
Using the Glob operation all public items in a namespace can be brought into scope
use std::collections::*;
Modules in Separate Files
A file with the name of the module need to be created
If the module consists on child modules then a folder with the name of the parent module has to be created
In the folder a file with the name of the child module is created
Separating Modules into Different Files - The Rust Programming Language