← [ BACK_TO_NOTES ]

Rust 项目结构与分层

bin/lib 拆分、模块分层、依赖方向与中小型服务的推荐骨架。

#synthesis #growing #dev #rust

[!info] related notes

Rust 项目结构与分层

这个概念为什么出现

能编译不等于可维护。
可以约定入口、领域与接口适配器的位置及依赖方向;小工具不必预先建立所有层。

[!abstract] 一句话理解 二进制保持瘦入口;核心逻辑放 library;按领域模块划分;外层依赖内层,避免循环与“utils 垃圾场”。

分层示意与独立可运行函数

场景:订单服务骨架目录

order-service/
  Cargo.toml
  src/
    main.rs          # 组装与启动
    lib.rs           # 核心导出
    domain/          # 实体与规则
      mod.rs
      order.rs
    app/             # 用例服务
      mod.rs
    infra/           # 文件/HTTP/DB 适配
      mod.rs
  tests/
    smoke.rs

main.rs 只做:读配置 → 构造服务 → 跑。
domain 不依赖 infra。这是可选架构约定,不是 Rust 语法要求;只有目录不会自动声明模块,还需在 lib.rs/mod.rs 中声明 mod 并控制可见性。下面是独立函数示例,不是完整目录工程。

// 示意:领域纯函数不依赖框架
pub fn can_cancel(status: &str) -> bool {
    status == "created" || status == "paid"
}

fn main() {
    println!("cancel_allowed={}", can_cancel("paid"));
}

结合场景再看三个关注点

  1. 可测性:domain 无 IO
  2. 替换 infra 不影响规则
  3. workspace 可再拆 crate

核心概念与准确模型

  • 依赖方向:main → app → domain,infra → 实现接口
  • feature 开关可选能力
  • examples/ 放可运行样例
  • benches/ 放基准

设计动机

  • 长期演进
  • 测试金字塔可行
  • 团队导航成本下降

边界与误区

  • 过早微服务/过多 crate
  • crate 的普通依赖图不能形成循环;同一 crate 内模块互相引用不等于 Cargo 循环依赖,分层约束需另外审查
  • 把框架类型漏进 domain

[!warning] 常见误区:所有代码塞 main.rs 随业务复杂度增长可提取可测试的 lib API;短小单文件 CLI 无需为形式分层。

工程实践

  1. 先单 crate 分层,再 workspace
  2. 公共 API 最小化
  3. README 画模块图
  4. 通过可见性、crate 边界和定向检查维护分层;cargo-deny 检查依赖的许可证、来源等策略,不自动检查 src 内的模块依赖方向

本节总结

  • 瘦 bin 厚 lib
  • 领域独立
  • 依赖单向

自测题

  1. 为什么 domain 不该依赖具体 DB crate?
  2. tests/ 放什么?
参考答案
  1. 便于替换与单测,避免基础设施细节污染规则。
  2. 面向公共 API 的集成/端到端级测试。

延伸阅读与资料来源

资料类型支撑内容
Cargo project layout官方目录约定
The Book — Packages官方书组织
创建于 2026/7/15 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本