Hello everyone, new episode of rust-series is here, today we will discuss modules. Up to now we always put our code into one .rs file and it is fine for our limited needs, indeed. But in general, when you work on something it's not practical at all. It's necessary to categorize things into multiple files and modules to have concerns separated. There things to remember:
See function in module and its calling from main function:
mod my {
pub fn public_module_function() {
private_module_function();
}
fn private_function() {
println!("private module function called");
}
}
fn main() {
my::public_module_function();
}
If we use some module function multiple times, it's worth to alias it with use to bind path to a new name.
fn main() {
use my::public_module_function;
public_module_function();
public_module_function();
public_module_function();
}
We can nest modules as we want
mod my {
mod math {
pub fn calculate() {
println("calculated");
}
}
mod graphics {
pub fn draw_box() {
println!("box drawn");
}
}
}
fn main() {
my::math::calculate();
my::graphics::drawbox();
}
Sometime we need to remove ambiguity, super and self are useful for this. Check this piece of code:
fn common_name_function() {
println!("common_name_function outside module");
}
mod my {
fn common_name_function() {
println!("common_name_function in module");
}
mod math {
pub fn calculate() {
println!("calculating...");
}
}
mod graphics {
pub fn draw() {
println!("drawing...");
}
}
pub fn calculate_and_draw() {
common_name_function();
super::common_name_function();
self::math::calculate();
self::graphics::draw();
}
}
fn main() {
my::calculate_and_draw();
}
# output
common_name_function in module
common_name_function outside module
calculating...
drawing...
It's also useful to split modules into multiple files.
Assume we have two files - main.rs and my.rs. Main.rs will contain main function and my.rs my module.
We just define function but don't forget pub keyword to make sure function will be publicly accessible.
pub fn my_mod_function() {
println!("my_mod_function called!");
}
Here we just need to say we will use my mod with mod keyword.
mod my;
fn main() {
my::my_mod_function();
}
# output
my_mod_function called!
Note that "mod my" makes Rust searching for my.rs file or my/mod.rs file.
We ca also refer additional modules like with pub mod. Check the example
pub mod additional;
pub fn additional_mod_function() {
println!("additional_mod_function called!")
}
fn main() {
my::additional::additional_mod_function();
}
# output
additional_mod_function called!
With these principle you can create as complex module structures as you wish.
That's all for today, thank you for your appreciations, feel free to comment and point out possible mistakes (first 24 hours works the best but any time is fine). Jesus bless your programming skills, use them wisely and see you next time.
Meanwhile you can also check official documentation to find more about discussed crates and modules: