首页 / Rust 入门教程 / 项目结构解析

Rust 入门教程

项目结构解析

本教程共 78 篇 · 第 6 篇 · 更新于 2026-08-08 · 约 7 分钟阅读

RustRust 入门教程Cargo.toml项目结构src 目录targetCargo.lock

本节目标:看清 cargo 生成的项目里每个文件和目录是干嘛的,尤其是 Cargo.toml 的配置项和 target 目录的作用。

上一章用 cargo new 一键生成了项目,你大概没细看里面到底有什么。这一章我们把它拆开,搞清楚每个部件的用途。搞明白结构,以后遇到编译产物去哪了、依赖怎么声明,你就不会发懵。

6-1 顶层长什么样

hello_cargo 目录里默认有两样东西:

hello_cargo/
├── Cargo.toml
└── src/
    └── main.rs

Cargo.toml 是项目的”说明书”——名字、版本、依赖都写在这。 src/ 是放源码的地方,入口文件 main.rs 已经躺在里面。cargo 约定:所有 .rs 源文件都放在 src 下,根目录只放配置和文档。

Note

为什么把源码塞进 src?这是 cargo 的约定优于配置思想:大家都这么摆,工具链和别人一眼就懂。别把 .rs 文件随便丢在根目录,cargo 不会主动去编译它。

6-2 读懂 Cargo.toml

打开 Cargo.toml,内容大概这样:

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]

[package] 这一段描述你的项目自身:

  • name:crate 名,发布到仓库时别人靠它找到你。
  • version:语义化版本号,初始通常是 0.1.0
  • edition:用的 Rust Edition,本教程统一 2024。这就是第一章说的”语法方言版本”,写在这就定下了。

[dependencies] 这一段目前是空的,专门用来列你依赖的第三方 crate。以后要用人家的库,就写在这里,比如:

[dependencies]
serde = "1.0"

cargo 会自动去官方仓库 crates.io 下载并管理版本。这就是 Rust 的包管理,比你手动下载 .h / .lib 文件省事太多。

6-3 src 目录与 main.rs

src/main.rs 就是程序入口,里面是 cargo 预先写好的:

fn main() {
    println!("Hello, world!");
}

你现在可以打开它改改文字,再 cargo run,就能看到自己的改动生效。这是你和项目互动的最直接入口。

如果你想写库(给别人用、自己不含 main 函数),入口文件叫 src/lib.rscargo new --lib 会生成它。bin 项目和 lib 项目在 src 下的入口文件名不同,记住这点即可。

6-4 target 目录:构建产物的家

每次你 cargo build / cargo run,cargo 都会把编译出来的东西放进 target/ 目录。它长这样:

target/
└── debug/
    ├── hello_cargo          (可执行文件)
    ├── hello_cargo.exe      (Windows 上)
    └── ...一堆中间文件

debug 是调试构建;加了 --release 会多出一个 target/release/,里面是优化后的成品。

这个目录通常很大、文件很多,而且完全能靠源码重新生成。所以——

Warning

target/ 千万别手动改里面的文件,也别提交进版本库(git)。它纯粹是编译的副产品,删了重编就会再生。正经项目都会把 target/ 写进 .gitignore。你只需知道”产物在这”,不必关心里面的细节。

6-5 Cargo.lock:依赖的锁文件

第一次构建后,根目录还会出现一个 Cargo.lock。它记录了这一次实际用到的每个依赖的精确版本号。

它的作用是”锁版本”:你和同事各 clone 一次项目,即使期间某个依赖发了新版本,Cargo.lock 也能保证两人编出来的结果一致,避免”我这边能跑你那边崩”的惨剧。

  • 二进制应用项目:应该把 Cargo.lock 提交进 git,锁定所有人的构建。
  • 对**库(lib)**项目:通常不提交,因为库的使用者会自己解析依赖。
Tip

刚上手你不用纠结这条规矩。记住 Cargo.lock 是 cargo 自动维护的、别手改它,就够了。

6-6 自己加源码文件怎么被编译

你在 src 下新建 src/foo.rs 并写点函数,它不会自动被编进程序。Rust 用 mod 声明模块关系。最简单的办法:在 main.rs 里写 mod foo;,告诉编译器”我有个 foo 模块”。具体的模块机制属于进阶内容,这里先留个印象:源码文件要在 main.rs(或 lib.rs)里通过 mod 串联起来,cargo 才会编译它。

6-7 整体心智模型

把项目想成一家小工厂:Cargo.toml 是营业执照和采购单,src/ 是生产车间(你写代码的地方),target/ 是仓库(堆成品),Cargo.lock 是入库台账。cargo 这个厂长,按 Cargo.toml 的指示,把 src 里的原料加工成 target 里的成品。

理解了这套结构,你再看任何 Rust 开源项目都不会迷路。下一章我们正式进入语言本身,从”变量”这个最基础的概念讲起。

6-8 修改 Cargo.toml 后会发生什么

讲了项目结构,自然要问:当你在 Cargo.toml[dependencies] 里加了一个库,再 cargo build 会发生什么?cargo 会去官方仓库 crates.io 查这个库、下载它及其依赖、编译、写进 Cargo.lock。整个过程自动完成,你不用手动下任何文件。

[dependencies]
rand = "0.8"

加这一行后首次 cargo build,cargo 会拉取 rand 这个随机数库。之后 Cargo.lock 记下精确版本,再构建直接读缓存,又快又稳。target/ 里会多出 rand 的编译产物——你同样不用管它。

Warning

版本号 "0.8" 是”兼容区间”写法,cargo 会允许 0.8.x 里的小更新(按语义化版本规则,只更最后一位是兼容的)。想锁死某版本,写成 rand = "=0.8.5"(加等号)。新手暂用默认写法即可,知道 cargo 会自动帮你管理依赖版本就行。

Tip

想手动更新某个依赖到新版本,用 cargo update -p 库名。它只更新 Cargo.lock 里的版本,不动你的 Cargo.toml。这个项目结构里的每个文件,都是为”自动化依赖管理”服务的。

6-9 最小可运行项目清单

一个”最小可运行项目”到底需要什么?其实就三样:Cargo.toml(告诉 cargo 项目叫啥、啥版本)、src/main.rs(程序入口,含 fn main)、以及一个目录把它们装起来。其余的 target/Cargo.lock 都是跑起来后自动生成的,你从不需要手写。

Note

刚开始你完全不需要理解 Cargo.toml 里每个字段。只要知道”名字、版本、edition”这三行是啥意思,其余的等用到依赖时自然会加。Rust 的设计哲学是”最小可用起步,按需扩展”,别被一堆配置吓住。

6-10 工作区与多包预览

当项目变大、拆成多个相关的库时,cargo 还有个”工作区(workspace)“概念:一个顶层目录管多个 crate,共享一个 target/Cargo.lock,依赖只下载一份。这对中大型项目能显著省时省空间。入门阶段你用不到,但知道 cargo 能从小项目平滑扩展到工作区,心里有底。

Tip

你现在写的都是单 crate 小项目,完全不用碰工作区。如果以后看到一个仓库根目录有 Cargo.toml 且里面有 [workspace] 段、下面多个子目录各是独立 crate,那就是工作区结构。理解了”单项目 → 工作区”的演进,你看开源大项目时不慌。

6-11 小结

项目结构里:Cargo.toml 是配置与依赖清单,src/ 放源码、target/ 放构建产物(别提交进 git),Cargo.lock 锁版本。加依赖后 cargo 自动从 crates.io 拉取并编译。理解这套结构,你看任何 Rust 项目都不迷路。下一章进入语言本身,从变量讲起。