Cargo 项目结构
对比:
JS
JavaScriptmy-project/
├── package.json # 依赖声明
├── node_modules/ # 依赖目录
├── src/
│ ├── index.js
│ └── utils.js
└── .gitignoreRs
Rustmy-project/
├── Cargo.toml # 依赖声明(= package.json)
├── Cargo.lock # 锁文件(= package-lock.json)
├── src/
│ ├── main.rs # 二进制入口
│ ├── lib.rs # 库入口(可选)
│ └── utils.rs # 模块文件
└── .gitignore模块系统
// src/lib.rs
mod garden; // 声明模块,对应 src/garden.rs
mod kitchen { // 内联模块
pub fn cook() { println!("cooking!"); }
}
pub use garden::Vegetable; // 重新导出,简化外部路径// src/garden.rs
pub struct Vegetable {
pub name: String,
calories: u32, // 私有字段
}
impl Vegetable {
pub fn new(name: &str) -> Vegetable {
Vegetable { name: name.to_string(), calories: 0 }
}
}
pub mod seasonal; // 嵌套子模块,对应 src/garden/seasonal.rsRust 的可见性默认私有,pub 显式公开。这与 JS 相反(默认导出需要 export),但更安全:API 边界一目了然,不会意外暴露内部实现。
use:路径简化
use std::collections::HashMap;
use std::io::{self, Write}; // 同时引入 io 和 io::Write
use crate::garden::Vegetable; // crate:: 表示当前 crate 根
// as 重命名
use std::fmt::Result as FmtResult;
use std::io::Result as IoResult;Cargo.toml:依赖管理
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
reqwest = "0.11"
[dev-dependencies] # 仅测试用
criterion = "0.5"
[features] # 可选特性
default = []
postgres = ["sqlx/postgres"]features 系统是 Rust 生态的核心设计——crate 默认只编译必要代码,用户按需开启功能。这让二进制更小、编译更快,类比 tree-shaking 但发生在编译期。
Cargo Workspace:Monorepo
# workspace/Cargo.toml(根目录)
[workspace]
members = [
"crates/core",
"crates/web",
"crates/cli",
]
resolver = "2"workspace/
├── Cargo.toml # workspace 根
├── Cargo.lock # 共享锁文件
└── crates/
├── core/ # 共享逻辑库
│ ├── Cargo.toml
│ └── src/lib.rs
├── web/ # Axum Web 服务
│ ├── Cargo.toml # 依赖 core
│ └── src/main.rs
└── cli/ # CLI 工具
├── Cargo.toml # 依赖 core
└── src/main.rs# crates/web/Cargo.toml
[dependencies]
core = { path = "../core" } # 本地依赖发布到 Crates.io
# 登录(需要 crates.io 账号)
cargo login <token>
# 检查发布前
cargo check
cargo test
cargo doc --open # 预览文档
# 发布
cargo publish// 文档注释自动生成 docs.rs 页面
/// 将摄氏度转换为华氏度。
///
/// # Examples
/// ```
/// use my_crate::celsius_to_fahrenheit;
/// assert_eq!(celsius_to_fahrenheit(0.0), 32.0);
/// ```
pub fn celsius_to_fahrenheit(c: f64) -> f64 {
c * 9.0 / 5.0 + 32.0
}/// 注释中的 # Examples 代码块会被 cargo test 自动执行——文档即测试,文档永远是最新的。
Cargo Workspace 实战
从单 crate 项目演进到 workspace monorepo:拆分 core/web/cli 三个 crate,共享类型定义,统一依赖版本管理
视频即将上线
实战项目
发布一个 Crates.io 工具库
初级
构建一个字节格式化工具库(bytes-fmt):提供人类可读的字节大小显示(1.5 KB, 2.3 MB),添加完整文档注释、单元测试、示例代码,发布到 Crates.io。
模块系统Cargo.toml文档注释cargo publish