← Rust EnglishChapter 12 of 13

Modules

## Learning Objectives - Organize code with modules - Control visibility with pub - Use use statements - Work with crates and packages - Understand the module system ## Why Modules? Modules organize code into logical units: - Group related functionality - Control visibility (public/private) - Avoid name conflicts - Enable code reuse ## Module System Overview ```text crate └── module ├── submodule └── subsubmodule ``` ## Defining Modules ### Inline Modules ```rust mod network { fn connect() { println!("Connecting..."); } pub fn send(data: &str) { connect(); println!("Sending: {}", data); } } fn main() { network::send("hello"); } ``` ### Module File System ```text src/ ├── main.rs ├── network.rs (or network/mod.rs) └── network/ └── mod.rs ``` ### network.rs ```rust pub fn send(data: &str) { connect(); println!("Sending: {}", data); } fn connect() { println!("Connecting..."); } ``` ### main.rs ```rust mod network; fn main() { network::send("hello"); } ``` ## Visibility ### Public (pub) ```rust mod outer { pub mod inner { pub fn public_function() { println!("Public!"); } pub(crate) fn crate_public() { println!("Crate public!"); } fn private_function() { println!("Private!"); } } } fn main() { outer::inner::public_function(); // outer::inner::private_function(); // Error! } ``` ### Private ```rust mod outer { fn private() { println!("Private outer"); } pub fn public() { private(); // Can call private } mod inner { fn private_inner() {} pub fn public_inner() { private_inner(); // Can call sibling private } } pub mod public_inner { pub fn from_public_inner() {} } } ``` ### pub(super) and pub(in path) ```rust mod outer { pub mod middle { pub mod inner { pub fn function() {} } pub(in outer) fn outer_only() {} } pub fn use_inner() { middle::inner::function(); middle::outer_only(); // OK: within outer } } ``` ## use Statements ### Bringing Items into Scope ```rust mod network { pub fn send(data: &str) { println!("Sending: {}", data); } } use network::send; // Bring into scope fn main() { send("hello"); // Direct call } ``` ### Full Path ```rust use std::collections::HashMap; fn main() { let mut map = HashMap::new(); map.insert("a", 1); } ``` ### Nested Paths ```rust use std::collections::{HashMap, HashSet}; use std::io::{self, Write}; // Includes io itself // Or glob use std::collections::*; ``` ### Renaming with as ```rust use std::io::Result as IoResult; use std::fmt::Result as FmtResult; fn my_function() -> IoResult<()> { Ok(()) } ``` ### re-exporting with pub use ```rust mod inner { pub mod deeply { pub fn nested_function() {} } } pub use inner::deeply; fn main() { deeply::nested_function(); // Re-exported to outer scope } ``` ## Struct Visibility ```rust mod my_module { pub struct Secret { pub data: String, // Public field internal: String, // Private field (within crate) secret: String, // Private field (only in module) } impl Secret { pub fn new(data: String) -> Self { Secret { data, internal: data.clone(), secret: data, } } pub fn get_internal(&self) -> &str { &self.internal } } } fn main() { let s = my_module::Secret::new("secret".to_string()); println!("{}", s.data); // OK: public // println!("{}", s.internal); // Error: private println!("{}", s.get_internal()); // OK: accessor method } ``` ## Enum Visibility ```rust mod network { pub enum PacketType { Data, // Public by default Ack, } pub struct Packet { pub packet_type: PacketType, // Public field data: Vec, // Private field } impl Packet { pub fn new(packet_type: PacketType) -> Self { Packet { packet_type, data: Vec::new(), } } } } fn main() { let packet = network::Packet::new(network::PacketType::Data); println!("{:?}", packet.packet_type); } ``` ## Crates ### Library Crate ```text my_crate/ ├── Cargo.toml └── src/ └── lib.rs ``` ### src/lib.rs ```rust pub mod utilities { pub fn helper() {} } ``` ### Using Library Crate ```rust use my_crate::utilities; fn main() { utilities::helper(); } ``` ### Binary Crate ```text my_project/ ├── Cargo.toml └── src/ └── main.rs ``` ## Packages A package contains one or more crates: - One library crate (lib.rs) OR - One or more binary crates (bin/) ```text my_package/ ├── Cargo.toml ├── src/ │ └── main.rs └── src/ └── lib.rs (optional) ``` ## The Module Tree ```rust // src/main.rs or src/lib.rs mod network { // network.rs or network/mod.rs pub mod client; pub mod server; } mod database { // database.rs or database/mod.rs pub mod connection; } fn main() { network::client::connect(); database::connection::connect(); } ``` ## Best Practices ### File Structure ```text src/ ├── main.rs (binary crate root) ├── lib.rs (library crate root) ├── network/ │ ├── mod.rs │ └── client.rs │ └── server.rs └── database/ ├── mod.rs └── connection.rs ``` ### Module Naming ```rust mod my_module; // snake_case mod myGreatModule; // Don't do this ``` ### Use Conventions ```rust // Bring parent module into scope mod outer { pub mod inner { pub fn function() {} } } mod outer2 { pub use super::outer::inner; // Re-export from parent pub mod nested { pub fn call_function() { super::function(); // Call parent's function } } } ``` ## Summary - Modules organize code logically - `mod` keyword declares modules - Files can be modules: `mod name;` looks for `name.rs` or `name/mod.rs` - `pub` makes items public - Private items only visible within declaring module - `use` brings items into scope - `pub use` re-exports items - `super` refers to parent module - Packages contain crates (one lib + optional bins)

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →