Rust modules
Referance : Modules - Rust By Example
Rust uses a module system to organize and manage code across multiple files and crates. The module system helps in code encapsulation, reusability, and namespace management.
What is a Module in Rust?
A module in Rust is a way to group related functions, structs, enums, traits, and even other modules together.
Lets learn :
Declaring and Using Modules
2.1 Declaring Modules
A module can be declared using the mod keyword:
Ex for simple module :
mod greetings {
pub fn chant() {
println!("Jai Shree Ram!");
}
}
fn main() {
greetings::chant();
}
/*Jai Shree Ram!*/
Nested Modules:
Modules can be nested within other modules:
mod outer {
pub mod inner {
pub fn say_hello() {
println!("Jai Bajrang Bali!");
}
}
}
fn main() {
outer::inner::say_hello();
}
/*
Jai Bajrang Bali!
*/
Controlling Visibility (pub)
By default, all items inside a module are private. You need pub to make them accessible outside the module.
mod my_module {
fn private_function() {
println!("Jai Shree Ram -This is private!");
}
pub fn public_function() {
println!("Om Namah Shivaya - This is public!");
}
}
fn main() {
// my_module::private_function(); // ❌ ERROR: function is private
my_module::public_function(); // ✅ Works because it is public
}
/*
Om Namah Shivaya - This is public!
*/
Making a Struct’s Fields Public
In Rust, when a struct has private fields, you can't directly initialize those fields from outside the module.
mod my_module {
pub struct Person {
pub name: String,
age: u32, // This field is private
}
}
fn main() {
/*
If you uncomment below code it cause the ❌ ERROR:
The reason is age is private and cant be used.
let person = my_module::Person {
name: "Alice".to_string(),
//age: 30, // ❌ ERROR: `age` is private
};
*/
println!("Person's name: {}", person.name);
}
However, we can provide a public constructor function within the module to initialize the struct.
Here's how you can modify above code to include a constructor function for the Person struct:
mod my_module {
pub struct Person {
pub name: String,
age: u32, // This field is private
}
impl Person {
// Public constructor function to initialize the struct
pub fn new(name: String, age: u32) -> Person {
Person { name, age }
}
// Public method to access the private field
pub fn get_age(&self) -> u32 {
self.age
}
}
}
fn main() {
let person = my_module::Person::new("Jai ShreeRam".to_string(), 30);;
println!("Person's name: {}", person.name);
println!("Person's age: {}", person.get_age());
}
/*
Person's name: Jai ShreeRam
Person's age: 30
*/
Module Files and Folders
Rust modules can be split across multiple files.
Creating Modules in Separate Files
Instead of writing all modules in one file, Rust allows you to structure your project like this:
src/
│── main.rs
│── my_module.rs
Linking my_module.rs
In main.rs, declare the module:
File: main.rs
mod my_module; // Rust will look for my_module.rs
fn main() {
my_module::say_hello();
}
Then, in my_module.rs:
File: my_module.rs
pub fn say_hello() {
println!("Jai Shree Ram!");
}
Using Submodules (mod.rs)
When a module has submodules, Rust allows you to structure it using folders.
Example Directory Structure
src/
│── main.rs
│── my_module/
│ │── mod.rs
│ │── sub_module.rs
File: main.rs
mod my_module;
fn main() {
my_module::sub_module::say_hello();
}
File: my_module/mod.rs
pub mod sub_module;
File: my_module/sub_module.rs
pub fn say_hello() {
println!("Jai Shree Ram sub_module!");
}
The use Keyword: Bringing Items into Scope
If a module is deeply nested, you can use use to make code shorter.
use imports greet directly, so we don’t need outer::inner:: every time.
use outer::inner::greet;
mod outer {
pub mod inner {
pub fn greet() {
println!("Jai Shree Ram from inner!");
}
}
}
fn main() {
greet();
}
The super Keyword: Accessing Parent Modules
You can use super to refer to the parent module.
mod parent {
pub mod child {
pub fn greet() {
super::say_hello(); // super keyword is used here
}
}
pub fn say_hello() {
println!("Jai Shree Ram from parent!");
}
}
fn main() {
parent::child::greet();
}
The crate Keyword: Accessing Root Module
The crate keyword refers to the root module.
mod my_module {
pub fn greet() {
crate::say_hello(); // crate is used here
}
}
fn say_hello() {
println!("Jai Shree Ram from root!");
}
fn main() {
my_module::greet();
}
Modules and Crates
Example: Using External Crates
[dependencies]
rand = "0.8"
use rand::Rng; // Import from external crate
fn main() {
let num: i32 = rand::thread_rng().gen_range(1..10);
println!("Random number: {}", num);
}