2.9 Modules and Crates: Code Organization
Modules encapsulate Rust source code, hiding internal implementation details. Crates are the fundamental units of code compilation and distribution in Rust.
2.9.1 Modules (mod
)
Modules provide namespaces and control the visibility of items (functions, structs, etc.). Items within a module are private by default and must be explicitly marked pub
(public) to be accessible from outside the module.
// Define a module named 'greetings' mod greetings { // This function is private to the 'greetings' module fn default_greeting() -> String { // `to_string` is a method that converts a string literal (&str) // into an owned String. "Hello".to_string() } // This function is public and can be called from outside pub fn spanish() { println!("{} in Spanish is Hola!", default_greeting()); } // Modules can be nested pub mod casual { pub fn english() { println!("Hey there!"); } } } fn main() { // Call public functions using the module path `::` greetings::spanish(); greetings::casual::english(); // greetings::default_greeting(); // Error: private function }
2.9.2 Splitting Modules Across Files
For larger projects, a module’s contents can be placed in a separate file instead of directly within its parent file. When you declare a module using mod my_module;
in a file (e.g., main.rs
or lib.rs
), the compiler looks for the module’s code in one of two locations:
- In
my_module.rs
: A file namedmy_module.rs
located in the same directory as the declaring file. This is the preferred convention since the Rust 2018 edition. - In
my_module/mod.rs
: A file namedmod.rs
inside a subdirectory namedmy_module/
. This is an older convention but still supported.
Cargo handles the process of finding and compiling these files automatically based on the mod
declarations.
2.9.3 Crates
A crate is the smallest unit of compilation and distribution in Rust. There are two types:
- Binary Crate: An executable program with a
main
function (like themy_project
example earlier). - Library Crate: A collection of reusable functionality intended to be used by other crates (no
main
function). Compiled into a.rlib
file by default (Rust’s static library format).
A Cargo project (package) can contain one library crate and/or multiple binary crates.
2.9.4 Comparison with C
- Rust’s module system replaces C’s convention of using header (
.h
) and source (.c
) files along with#include
. Rust modules provide stronger encapsulation and avoid issues related to textual inclusion, multiple includes, and managing include guards. - Rust’s crates are analogous to libraries or executables in C, but Cargo integrates dependency management seamlessly, unlike typical C workflows that often require manual library linking and configuration.