Reading — step 1 of 6
Learn
Rust's module system organizes code into a hierarchy and controls visibility. Every Rust file defines a module; modules can nest and form a crate.
Defining modules
// In src/lib.rs or src/main.rs
mod math {
pub fn add(a: i32, b: i32) -> i32 { a + b }
fn private_helper() {}
}
fn main() {
let sum = math::add(3, 4);
// math::private_helper(); // ✗ private
}
mod declares a module. Items are private by default — pub exposes them.
Files and modules
A module can be in its own file:
// src/main.rs:
mod math; // declares module from math.rs (or math/mod.rs)
fn main() {
println!("{}", math::add(3, 4));
}
// src/math.rs:
pub fn add(a: i32, b: i32) -> i32 { a + b }
For nested modules:
src/
main.rs
math/
mod.rs // or math.rs (modern style)
geometry.rs // submodule math::geometry
// src/math/mod.rs (or src/math.rs):
pub mod geometry; // expose submodule
pub fn add(a: i32, b: i32) -> i32 { a + b }
Visibility levels
fn private() {} // visible only in this module
pub fn public() {} // visible everywhere
pub(crate) fn crate_only() {} // visible within this crate
pub(super) fn parent_only() {} // visible in parent module
pub(in path) fn restricted() {} // visible in specific path
Least-privilege by default. Promote items to pub only when consumers need them.
use statements
Bring names into scope to avoid long paths:
use std::collections::HashMap;
use std::io::{self, Read, Write}; // multiple from one path
use std::fmt::Display as Disp; // alias
// In a function:
let mut map: HashMap<String, i32> = HashMap::new();
Crates and Cargo
A crate is a compilation unit — either a binary (with main) or a library. Cargo (Rust's package manager) handles dependencies via Cargo.toml:
[package]
name = "my_project"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
cargo build, cargo run, cargo test, cargo check are the daily workflow.
Re-exports
A library can curate its public API by re-exporting:
// src/lib.rs:
mod internal;
pub use internal::PublicType; // surface only this from the internal module
Keeps the internal layout flexible while presenting a stable API.
Common mistakes
- Forgetting
pubon items consumers need — "private item" errors. - Confusing the file name and module name —
src/foo.rsdefines modulefoo(parent offoodeclaresmod foo;). - Importing the entire module instead of specific items — bloats compile times in big projects.
usestatements at function scope — works but is unconventional. Put them at top of file or module.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…