Shiklo Tools
PDF40
Image20
Calculators & Converters25
Text & Writing13
Developer26
Video14
Audio14
Document14
Data & Spreadsheet12
Web & SEO9
OCR & Scanning5
Archive & File12
Security & Privacy23
Health & Medical29
QR & Barcode5

Rust Modules

As programs grow, keeping everything in one long file gets messy, just like keeping all your papers in one big pile. Modules are Rust's folders for code. They group related functions, structs and enums together, and they decide what the rest of the program is allowed to see.

A module inside one file

You create a module with mod and a name, and put the code in curly brackets. To use something from the module, write the module name, two colons, and the item's name. That is called a path.

mod greetings {
    pub fn hello(name: &str) -> String {
        format!("Hello, {}!", name)
    }

    pub fn goodbye(name: &str) -> String {
        format!("Goodbye, {}. See you soon!", name)
    }
}

fn main() {
    println!("{}", greetings::hello("Isha"));
    println!("{}", greetings::goodbye("Isha"));
}
Output
Hello, Isha!
Goodbye, Isha. See you soon!

pub: what others may use

Everything in a module is private by default: only code inside the module can use it. The word pub (for public) opens an item up to the rest of the program. This lets a module keep its helper functions to itself and show only a tidy set of public ones. Try removing a pub above and running the program: the compiler explains that the function is private.

use: shorter paths

Writing long paths again and again gets tiring. use brings a name into scope, so you can write it on its own. You have done this already with use std::io; and use std::collections::HashMap;, which are paths into Rust's standard library.

mod shop {
    pub mod pricing {
        pub fn with_tax(price: f64) -> f64 {
            price * 1.18
        }
    }
}

use shop::pricing::with_tax;

fn main() {
    println!("{:.2}", with_tax(100.0));
    println!("{:.2}", with_tax(250.0));
}
Output
118.00
295.00

Modules can live inside other modules, as pricing lives inside shop. Each level needs its own pub to be reachable from outside.

Splitting a program into files

When a module gets big, move it to its own file. Write mod geometry; with a semicolon in main.rs, and Rust looks for the code in a file called geometry.rs next to it. In our editor, add the file with the new file button above the file list. The example below opens both files when you press Try it.

Example (2 files)Try it in the editor
main.rs
mod geometry;

use geometry::Rectangle;

fn main() {
    let room = Rectangle::new(4.0, 3.0);
    println!("Area: {}", room.area());
    println!("Paint needed for the walls: {:.1} litres", geometry::paint_litres(&room, 2.7));
}
geometry.rs
pub struct Rectangle {
    pub width: f64,
    pub length: f64,
}

impl Rectangle {
    pub fn new(width: f64, length: f64) -> Rectangle {
        Rectangle { width, length }
    }

    pub fn area(&self) -> f64 {
        self.width * self.length
    }
}

// One litre covers about 10 square metres.
pub fn paint_litres(room: &Rectangle, wall_height: f64) -> f64 {
    let walls = 2.0 * (room.width + room.length) * wall_height;
    walls / 10.0
}
Output
Area: 12
Paint needed for the walls: 3.8 litres

The file geometry.rs is the module geometry, without any mod geometry { } around its contents. Struct fields have their own privacy too: here width and length are pub, so other modules may read them.

Practice exercises

  1. Make a module maths with public functions square and cube, and call them from main.
  2. Add a private helper function to the module and see what happens when main tries to call it.
  3. Move the maths module into its own file maths.rs and use it with mod maths;.