模块系统
Rust 的模块系统允许您组织代码,控制作用域和私有性。模块系统包括包(packages)、单元包(crates)、模块(modules)和路径(paths)。
包和单元包
包(Package)
包是提供一系列功能的一个或多个单元包。包含有一个 Cargo.toml
文件,阐述如何去构建这些单元包。
toml
# Cargo.toml
[package]
name = "my_project"
version = "0.1.0"
edition = "2024"
[dependencies]
单元包(Crate)
单元包是 Rust 在编译时最小的代码单位。单元包可以包含模块,这些模块可以定义在其他文件,然后和单元包一起编译。
rust
// src/main.rs - 二进制单元包根
fn main() {
println!("Hello, world!");
}
rust
// src/lib.rs - 库单元包根
pub fn add(left: usize, right: usize) -> usize {
left + right
}
模块定义
内联模块
rust
// src/lib.rs
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() {}
}
}
pub fn eat_at_restaurant() {
// 绝对路径
crate::front_of_house::hosting::add_to_waitlist();
// 相对路径
front_of_house::hosting::add_to_waitlist();
}
文件模块
rust
// src/lib.rs
mod front_of_house;
pub fn eat_at_restaurant() {
front_of_house::hosting::add_to_waitlist();
}
rust
// src/front_of_house.rs
pub mod hosting {
pub fn add_to_waitlist() {}
}
pub mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
目录模块
src/
├── lib.rs
└── front_of_house/
├── mod.rs
├── hosting.rs
└── serving.rs
rust
// src/front_of_house/mod.rs
pub mod hosting;
pub mod serving;
rust
// src/front_of_house/hosting.rs
pub fn add_to_waitlist() {}
pub fn seat_at_table() {}
rust
// src/front_of_house/serving.rs
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
可见性和私有性
公有和私有
rust
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
fn private_function() {} // 私有函数
}
mod serving { // 私有模块
fn take_order() {}
}
}
pub fn eat_at_restaurant() {
// 可以访问公有函数
front_of_house::hosting::add_to_waitlist();
// 不能访问私有函数
// front_of_house::hosting::private_function(); // 错误!
// 不能访问私有模块
// front_of_house::serving::take_order(); // 错误!
}
结构体和枚举的可见性
rust
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 enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
// 创建结构体实例
let mut meal = back_of_house::Breakfast::summer("Rye");
// 可以修改公有字段
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
// 不能访问私有字段
// meal.seasonal_fruit = String::from("blueberries"); // 错误!
// 枚举的所有变体都是公有的
let order1 = back_of_house::Appetizer::Soup;
let order2 = back_of_house::Appetizer::Salad;
}
use 关键字
基本 use
rust
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
use 的习惯用法
rust
use std::collections::HashMap;
use std::fmt::Result;
use std::io::Result as IoResult; // 使用 as 重命名
fn function1() -> Result {
// --snip--
Ok(())
}
fn function2() -> IoResult<()> {
// --snip--
Ok(())
}
fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
}
嵌套路径
rust
// 不使用嵌套路径
use std::cmp::Ordering;
use std::io;
// 使用嵌套路径
use std::{cmp::Ordering, io};
// 更复杂的例子
use std::io::{self, Write};
glob 运算符
rust
use std::collections::*;
fn main() {
let mut map = HashMap::new();
let mut set = HashSet::new();
}
模块组织实例
餐厅管理系统
rust
// src/lib.rs
mod front_of_house;
mod back_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::seat_at_table();
let mut meal = back_of_house::Breakfast::summer("Rye");
meal.toast = String::from("Wheat");
let order1 = back_of_house::Appetizer::Soup;
}
rust
// src/front_of_house.rs
pub mod hosting;
pub mod serving;
rust
// src/front_of_house/hosting.rs
pub fn add_to_waitlist() {
println!("Adding to waitlist");
}
pub fn seat_at_table() {
println!("Seating at table");
}
rust
// src/front_of_house/serving.rs
fn take_order() {
println!("Taking order");
}
fn serve_order() {
println!("Serving order");
}
fn take_payment() {
println!("Taking payment");
}
rust
// src/back_of_house.rs
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 enum Appetizer {
Soup,
Salad,
}
fn fix_incorrect_order() {
cook_order();
super::front_of_house::serving::serve_order();
}
fn cook_order() {
println!("Cooking order");
}
工作空间
创建工作空间
toml
# Cargo.toml (工作空间根目录)
[workspace]
members = [
"adder",
"add_one",
]
toml
# adder/Cargo.toml
[package]
name = "adder"
version = "0.1.0"
edition = "2024"
[dependencies]
add_one = { path = "../add_one" }
toml
# add_one/Cargo.toml
[package]
name = "add_one"
version = "0.1.0"
edition = "2024"
rust
// add_one/src/lib.rs
pub fn add_one(x: i32) -> i32 {
x + 1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(3, add_one(2));
}
}
rust
// adder/src/main.rs
use add_one;
fn main() {
let num = 10;
println!("Hello, world! {} plus one is {}!", num, add_one::add_one(num));
}
路径和可见性规则
路径类型
rust
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// 绝对路径
crate::front_of_house::hosting::add_to_waitlist();
// 相对路径
front_of_house::hosting::add_to_waitlist();
}
super 关键字
rust
fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order(); // 使用 super 访问父模块
}
fn cook_order() {}
}
self 关键字
rust
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use self::front_of_house::hosting; // 使用 self
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
实际项目结构
Web 应用项目结构
src/
├── main.rs
├── lib.rs
├── models/
│ ├── mod.rs
│ ├── user.rs
│ └── post.rs
├── handlers/
│ ├── mod.rs
│ ├── auth.rs
│ └── api.rs
├── utils/
│ ├── mod.rs
│ ├── database.rs
│ └── validation.rs
└── config/
├── mod.rs
└── settings.rs
rust
// src/lib.rs
pub mod models;
pub mod handlers;
pub mod utils;
pub mod config;
pub use models::{User, Post};
pub use handlers::{auth, api};
rust
// src/models/mod.rs
pub mod user;
pub mod post;
pub use user::User;
pub use post::Post;
rust
// src/models/user.rs
#[derive(Debug)]
pub struct User {
pub id: u32,
pub username: String,
pub email: String,
}
impl User {
pub fn new(id: u32, username: String, email: String) -> User {
User { id, username, email }
}
}
rust
// src/handlers/mod.rs
pub mod auth;
pub mod api;
rust
// src/handlers/auth.rs
use crate::models::User;
pub fn login(username: &str, password: &str) -> Option<User> {
// 登录逻辑
if username == "admin" && password == "password" {
Some(User::new(1, username.to_string(), "admin@example.com".to_string()))
} else {
None
}
}
pub fn logout() {
println!("User logged out");
}
条件编译
cfg 属性
rust
// src/lib.rs
#[cfg(target_os = "windows")]
mod windows_specific {
pub fn do_windows_stuff() {
println!("Windows specific code");
}
}
#[cfg(target_os = "linux")]
mod linux_specific {
pub fn do_linux_stuff() {
println!("Linux specific code");
}
}
#[cfg(feature = "advanced")]
mod advanced_features {
pub fn advanced_function() {
println!("Advanced feature");
}
}
pub fn cross_platform_function() {
#[cfg(target_os = "windows")]
windows_specific::do_windows_stuff();
#[cfg(target_os = "linux")]
linux_specific::do_linux_stuff();
#[cfg(feature = "advanced")]
advanced_features::advanced_function();
}
测试模块
rust
// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, 1), 0);
}
}
练习
练习 1:图书馆管理系统
创建一个图书馆管理系统,包含书籍、用户、借阅等模块。
练习 2:电商系统
设计一个简单的电商系统,包含商品、订单、用户、支付等模块。
练习 3:重构现有代码
将一个大的 main.rs 文件重构为多个模块。
练习 4:工作空间项目
创建一个包含多个相关库的工作空间项目。
下一步
掌握了模块系统后,您可以继续学习:
- 错误处理 - 优雅处理错误
- 泛型 - 编写通用代码
- 特征 (Traits) - 定义共同行为
模块系统是组织大型 Rust 项目的基础,掌握它将帮助您构建可维护的应用程序!