跳到主要内容

模块基础(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 关键字来简化模块路径的使用。