模块基础(Module Basics)
模块(Module)是 Rust 中组织代码的基本单位。它们帮助你将相关的功能组织在一起,控制代码的可见性,并创建清晰的代码结构。
什么是模块?
模块是一个命名空间,包含函数、结构体、枚举、常量、其他模块等定义。模块帮助你:
- 组织代码:将相关功能分组
- 控制可见性:决定哪些代码对外部可见
- 避免命名冲突:不同模块可以有同名的项目
- 创建层次结构:模块可以嵌套
定义模块
内联模块
// 在同一文件中定义模块
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
fn main() {
// 模块中的函数默认是私有的
// front_of_house::hosting::add_to_waitlist(); // 错误!
}
文件模块
将模块定义在单独的文件中:
// src/main.rs
mod garden; // 声明模块,Rust 会查找 src/garden.rs 或 src/garden/mod.rs
fn main() {
garden::vegetables::Asparagus {};
}
// src/garden.rs
pub mod vegetables; // 公开的子模块
// src/garden/vegetables.rs
#[derive(Debug)]
pub struct Asparagus {}
模块路径
绝对路径和相对路径
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// 绝对路径 - 从 crate 根开始
crate::front_of_house::hosting::add_to_waitlist();
// 相对路径 - 从当前模块开始
front_of_house::hosting::add_to_waitlist();
}
super 关键字
使用 super 引用父模块:
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order(); // 调用父模块的函数
}
fn cook_order() {}
}
self 关键字
使用 self 引用当前模块:
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
pub fn seat_customer() {
self::add_to_waitlist(); // 调用同一模块的函数
add_to_waitlist(); // 也可以直接调用
}
}
}
可见性控制
pub 关键字
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {} // 公开函数
fn private_function() {} // 私有函数
}
mod private_module {
fn private_function() {}
}
}
// 结构体的可见性
mod back_of_house {
pub struct Breakfast {
pub toast: String, // 公开字段
seasonal_fruit: String, // 私有字段
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
let mut meal = back_of_house::Breakfast::summer("Rye");
meal.toast = String::from("Wheat"); // 可以修改公开字段
// meal.seasonal_fruit = String::from("blueberries"); // 错误!私有字段
}
枚举的可见性
mod back_of_house {
pub enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
let order1 = back_of_house::Appetizer::Soup;
let order2 = back_of_house::Appetizer::Salad;
}
模块树结构
Rust 的模块系统形成一个树状结构:
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
实际项目示例
项目结构
src/
├── main.rs
├── lib.rs
├── models/
│ ├── mod.rs
│ ├── user.rs
│ └── post.rs
├── handlers/
│ ├── mod.rs
│ ├── user_handler.rs
│ └── post_handler.rs
└── utils/
├── mod.rs
└── validation.rs
模块定义
// src/lib.rs
pub mod models;
pub mod handlers;
pub mod utils;
// src/models/mod.rs
pub mod user;
pub mod post;
// src/models/user.rs
#[derive(Debug)]
pub struct User {
pub id: u32,
pub name: String,
pub email: String,
}
impl User {
pub fn new(id: u32, name: String, email: String) -> Self {
User { id, name, email }
}
}
// src/handlers/mod.rs
pub mod user_handler;
pub mod post_handler;
// src/handlers/user_handler.rs
use crate::models::user::User;
pub fn create_user(name: String, email: String) -> User {
User::new(1, name, email)
}
pub fn get_user(id: u32) -> Option<User> {
// 实现获取用户逻辑
None
}
最佳实践
1. 模块命名
// 好的命名
mod user_management;
mod database_connection;
mod http_client;
// 避免的命名
mod UserManagement; // 使用 snake_case,不是 PascalCase
mod db_conn; // 避免过度缩写
2. 模块组织
// 将相关功能组织在一起
mod authentication {
pub mod login;
pub mod logout;
pub mod password_reset;
}
mod database {
pub mod connection;
pub mod migrations;
pub mod queries;
}
3. 合理使用可见性
mod internal {
pub(crate) fn internal_function() {} // 只在当前 crate 内可见
pub(super) fn parent_function() {} // 只在父模块可见
pub mod public_submodule {
pub fn public_function() {}
}
mod private_submodule {
fn private_function() {}
}
}
常见错误和解决方案
1. 模块未找到
// 错误:模块文件不存在
mod my_module; // 需要 src/my_module.rs 或 src/my_module/mod.rs
// 解决方案:创建对应的文件
2. 私有性错误
mod private_mod {
fn private_function() {}
}
fn main() {
// private_mod::private_function(); // 错误!函数是私有的
}
// 解决方案:添加 pub 关键字
mod private_mod {
pub fn public_function() {}
}
3. 路径错误
mod outer {
mod inner {
pub fn function() {}
}
}
fn main() {
// outer::inner::function(); // 错误!inner 模块是私有的
}
// 解决方案:使 inner 模块公开
mod outer {
pub mod inner {
pub fn function() {}
}
}
模块系统是 Rust 项目组织的基础,掌握它对于编写大型 Rust 应用程序至关重要。下一节我们将学习如何使用 use 关键字来简化模块路径的使用。