Rust 模块、crate 与可见性
crate/module 树如何组织代码;pub 可见性边界;path 与 use 的工程习惯。
#type / concept
#status / growing
#tech / dev
#resource / rust
[!info] 关联笔记
Rust 模块、crate 与可见性
这个概念为什么出现
代码增长后必须回答:谁可以调用谁?文件如何拆?
Rust 用 crate 为编译单元、module 为命名与可见性树、pub 控制边界。
[!abstract] 一句话理解 每个 crate 有一棵模块树;默认私有;
pub/pub(crate)等精确导出;use将路径导入作用域。
最小可运行示例
场景:计价 crate 内部模块——对外只导出 quote
库内部分 pricing 与 tax,外部只需 quote_total。
// 业务意图:隐藏内部税率细节,仅导出报价函数。
// 教学点:mod 树;pub(crate);pub use 重导出。
mod tax {
pub(crate) fn rate_bps() -> u32 { 1000 } // 10%
}
mod pricing {
use super::tax;
pub fn quote_total(net_cents: u32) -> u32 {
net_cents + net_cents * tax::rate_bps() / 10_000
}
}
pub use pricing::quote_total;
fn main() {
println!("total={}", quote_total(1000));
}
建议运行:cargo run
期望输出:
total=1100
结合场景再看三个关注点
- 内部
tax不对外 pub use做门面- 文件模块:
mod pricing;+pricing.rs同理
核心概念与准确模型
| 概念 | 含义 |
|---|---|
| package | Cargo.toml 对应单位 |
| crate | 编译单元(lib/bin) |
| module | 树节点 |
| path | crate::/super::/self:: |
可见性:默认私有;pub、pub(crate)、pub(super)、pub(in path)。
设计动机
- 封装不靠文件名约定 alone
- 明确 API 面
- 支持大代码库演进
边界与误区
- 过度
pub泄漏实现 - 循环模块依赖需重构
mod.rsvs 文件名模块风格(现代偏好foo.rs+foo/)
[!warning] 常见误区:把所有东西 pub 公共 API 是承诺;能 crate 内私有就私有。
工程实践
- 二进制 thin,逻辑在 lib
- 门面重导出稳定路径
- 集成测试只碰公共 API
- 用
cargo doc审视公开面
本节总结
- 模块树 + 可见性
- crate 边界
- use/pub use 管理路径
自测题
- package 与 crate 差别?
pub(crate)适用?
参考答案
- package 可含多个 crate(lib+bin…)。
- 同 crate 共享、不对外部承诺的 API。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| The Book — Packages Modules | 官方书 | 模块系统 |
| Rust Reference — Visibility | 规范 | 可见性 |