15
模块系统与工程化:Cargo、Workspace、clippy
Modules · Cargo · Workspace · clippy
小程序一个 main.rs 就够,长大了要拆模块、管依赖、跑测试。Rust 用 mod + pub + use 组织代码,用 Cargo 管一切工程化的事。
模块与可见性
// src/main.rs
mod math; // 声明子模块,对应 src/math.rs
fn main() {
println!("2+3={}", math::add(2, 3));
}
// src/math.rs —— 函数默认私有,pub 才对外可见
/*
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
fn internal() {} // 私有,外面看不见
*/
- 路径:
crate::绝对路径,super::上一级,self::当前。 - use 导入:
use std::collections::HashMap;,as重命名。 - pub use 重导出:对外重新包装模块路径,藏住内部结构。
Cargo.toml 与依赖管理
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
# axum = { git = "https://github.com/tokio-rs/axum" } # git 依赖
# local = { path = "../local-lib" } # 路径依赖
版本号语义:"1.2.3" 默认 >=1.2.3, <2.0.0(SemVer);"=1.2.3" 精确锁死。加依赖用 cargo add serde 最省心。二进制项目要提交 Cargo.lock,保证团队、CI、生产构建版本一致。
Workspace:多包项目
# 根 Cargo.toml:把多个 crate 绑成一个工作空间
[workspace]
members = [
"crates/common",
"crates/server",
"crates/client",
]
# cargo build -p server # 只构建某个包
测试、格式化、静态检查
// 单元测试:写在源码里,#[cfg(test)] 模块
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_works() {
assert_eq!(2 + 2, 4);
}
}
# 命令:cargo test / cargo fmt / cargo clippy
| 工具 | 干什么 |
|---|---|
| cargo test | 跑单元测试 + 集成测试(tests/ 目录)+ 文档里的示例(doc-test) |
| cargo fmt | 自动统一代码风格,别再为空格缩进吵架 |
| cargo clippy | 静态 lint,挑不地道的写法("Rust 方言"),生产 CI 必挂 |
| cargo doc | 从 /// 注释生成 HTML 文档,示例代码自动当测试跑 |
CI/CD 里标准动作:cargo fmt --check + cargo clippy + cargo test 三连。发布到 crates.io 用 cargo publish,发错了能 cargo yank 撤回(不让新项目用,但老项目还能拉到)。