模块与包管理¶
📚 章节概述¶
本章将介绍 Rust 的模块系统和包管理。模块系统帮助你组织代码,包管理器 Cargo 帮助你管理依赖和构建项目。
🎯 学习目标¶
- 理解模块系统的概念
- 学会定义和使用模块
- 掌握 use 关键字的使用
- 学会使用 Cargo 管理依赖
- 理解工作空间的使用
📖 模块系统¶
1.1 定义模块¶
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() {}
}
}
1.2 模块树¶
Text Only
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
1.3 使用模块¶
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();
}
1.4 使用 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();
}
1.5 使用 use 的惯用方式¶
Rust
// 好:引入结构体、枚举等的完整路径
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert(1, 2);
}
// 好:引入函数时,引入其父模块而非函数本身
use std::io;
// 然后通过 io::stdin() 调用,而不是直接 use std::io::stdin
// 好:使用嵌套路径引入多个项
use std::io::{self, Write};
1.6 使用 as 提供别名¶
Rust
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
Ok(())
}
fn function2() -> IoResult<()> {
Ok(())
}
1.7 重新导出¶
Rust
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
// 使用 pub use 重新导出
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
1.8 使用嵌套路径¶
Rust
// 旧方式
use std::cmp::Ordering;
use std::io;
// 新方式
use std::{cmp::Ordering, io};
// 使用 self
use std::io::{self, Write};
1.9 使用 glob 运算符¶
📦 包与 Crate¶
2.1 包和 Crate 的区别¶
- 包(Package):用于构建、测试和共享 crate 的 Cargo 功能
- Crate:模块树,产生一个库或可执行文件
2.2 创建包¶
2.3 包的结构¶
Text Only
my_project/
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── main.rs
│ └── bin/
│ └── extra_main.rs
└── tests/
└── integration_test.rs
2.4 定义模块¶
src/lib.rs
Rust
mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
src/front_of_house.rs
src/front_of_house/hosting.rs
🛠️ Cargo¶
3.1 Cargo.toml¶
TOML
[package]
name = "my_project"
version = "0.1.0"
edition = "2024"
authors = ["Your Name <you@example.com>"]
[dependencies]
serde = "1.0"
rand = "0.8"
[dev-dependencies]
criterion = "0.4"
[profile.release]
opt-level = 3
lto = true
3.2 添加依赖¶
TOML
[dependencies]
serde = { version = "1.0", features = ["derive"] }
rand = "0.8"
tokio = { version = "1.0", features = ["full"] }
3.3 依赖版本¶
TOML
# 精确版本
serde = "1.0.100"
# 兼容更新(推荐)
serde = "1.0"
# 范围版本
serde = ">=1.0.0, <2.0.0"
# 使用 commit hash
my_crate = { git = "https://github.com/user/repo", rev = "abc123" }
# 使用本地路径
my_crate = { path = "../my_crate" }
3.4 常用 Cargo 命令¶
Bash
# 构建项目
cargo build
# 运行项目
cargo run
# 运行测试
cargo test
# 检查代码
cargo check
# 生成文档
cargo doc --open
# 发布构建
cargo build --release
# 更新依赖
cargo update
# 清理构建文件
cargo clean
# 格式化代码
cargo fmt
# 代码检查
cargo clippy
📚 工作空间¶
4.1 创建工作空间¶
Cargo.toml
4.2 工作空间结构¶
Text Only
workspace/
├── Cargo.toml
├── adder/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
└── add_one/
├── Cargo.toml
└── src/
└── lib.rs
4.3 在工作空间中使用依赖¶
add_one/Cargo.toml
adder/src/main.rs
📝 练习题¶
练习 1:模块组织¶
Rust
// TODO: 创建一个模块结构
// - math 模块
// - basic 子模块(add, subtract)
// - advanced 子模块(multiply, divide)
// - utils 模块
// - string 子模块(reverse, uppercase)
// TODO: 在 main 函数中使用这些模块
fn main() {
// TODO: 实现
}
练习 2:use 关键字¶
Rust
// TODO: 使用 use 简化以下代码
mod math {
pub mod basic {
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
}
}
fn main() {
let result = math::basic::add(1, 2);
println!("Result: {}", result);
}
练习 3:Cargo 依赖¶
TOML
# TODO: 添加以下依赖到 Cargo.toml
# - serde: 1.0,启用 derive 特性
# - rand: 0.8
# - tokio: 1.0,启用 full 特性
[package]
name = "my_project"
version = "0.1.0"
edition = "2024"
[dependencies]
# TODO: 添加依赖
练习 4:工作空间¶
💡 最佳实践¶
1. 模块组织¶
Rust
// 好:按功能组织模块
mod auth;
mod database;
mod api;
mod utils;
// 避免:按类型组织模块
mod models;
mod controllers;
mod views;
2. 使用 pub use 重新导出¶
Rust
// 好
pub use self::error::{Error, Result};
mod error {
pub struct Error;
pub type Result<T> = std::result::Result<T, Error>;
}
// 避免
mod error {
pub struct Error;
pub type Result<T> = std::result::Result<T, Error>;
}
3. 指定依赖版本¶
4. 使用工作空间¶
⚠️ 常见错误¶
1. 模块可见性¶
Rust
// 错误:私有模块
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
}
}
fn main() {
front_of_house::hosting::add_to_waitlist(); // 编译错误
}
// 正确:使用 pub
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
2. use 路径¶
Rust
// 错误:use 引入函数
use std::collections::HashMap::new;
fn main() {
new();
}
// 正确:use 引入模块
use std::collections::HashMap;
fn main() {
HashMap::new();
}
3. 依赖版本冲突¶
TOML
# 错误:版本冲突
[dependencies]
crate1 = "0.1"
crate2 = { version = "0.2", features = ["crate1"] }
# 正确:使用兼容版本
[dependencies]
crate1 = "0.1"
crate2 = { version = "0.2", features = ["crate1_01"] }
📚 扩展阅读¶
🎯 本章小结¶
本章介绍了 Rust 的模块系统和包管理:
- ✅ 理解模块系统的概念
- ✅ 学会定义和使用模块
- ✅ 掌握 use 关键字的使用
- ✅ 学会使用 Cargo 管理依赖
- ✅ 理解工作空间的使用
下一章: 我们将学习 Rust 的并发编程,包括线程、通道、消息传递和共享状态。