跳转至

起步:安装、Hello World 与 Cargo

这一章讲三件事: 怎么把 Rust 装上;不借助任何工具手写一个程序并编译运行; 以及为什么真实项目一律用 Cargo 来管。读完你会拿到全书反复用到的那套基本动作—— 后面每一章的项目都是从 cargo new 开始的。不需要任何基础。

1. 先看全景:这一章走完,你的电脑上会有什么

主线例子就一件事:把一个 Hello, world! 程序从白纸做到能交出去。 全章围绕它走两条路,对比着走:

  路线 A(手写)              路线 B(Cargo)
  ─────────────────          ──────────────────────────────
  手写 main.rs               cargo new hello_cargo(脚手架自动建好)
  rustc main.rs              cargo build → 产物在 target/debug/
  ./main                     cargo run(改代码后自动重编译再跑)
                             cargo check(只查不编,最快)
                             cargo build --release(开优化,慢编译换快运行)

  图说:同一份代码,路线 A 是一条命令走到底,路线 B 是一组约定。
  两条路的终点一样;区别在代码一多,路线 A 就管不动了。

这一章在全书链条里的位置:它不给任何"语言机制",只给你工作台。 书特意把话说在前面——"绝大多数 Rust 项目都用 Cargo,本书其余部分假定你也用"1。 所以别把这一章当可跳过的安装指南:它立的那些约定(src 目录、Cargo.toml、target 目录)第 2 章起每一步都在用。

2. 装环境:rustup 管 Rust 的版本

Rust 通过一个叫 rustup 的命令行工具来安装,它管的是"Rust 的版本和配套工具", 而不是只装一次就完事。装完可以用一条命令验证:

$ rustc --version
rustc x.y.z (abcabcabc yyyy-mm-dd)

能看到版本号、提交哈希、提交日期三样,就说明装好了2。以后升级只需要 rustup update, 卸载是 rustup self uninstall,本地文档 rustup doc 离线就能翻。

这里只解释一个后面会反复出现的词。

编译器(compiler)是把人写的源代码翻译成机器能直接执行的文件的程序。 rustc 就是 Rust 的编译器,你写的 .rs 文件经它之手变成可执行文件。 在这一行它是个普通角色,但它的脾气贯穿全书:它不光翻译,还挑错—— 而且挑得比多数语言的编译器狠得多(第 4 章起你会一直被它拦)。

两个安装细节值得知道,都是"踩坑时才想起"型的:

  • 还需要一个链接器(linker,把编译产物拼成一个可执行文件的程序)。 一般系统自带;报链接错误就装个 C 编译器,它通常附赠链接器, 而且有些常用 Rust 包本身就依赖 C 代码3。
  • Windows 上安装器会提示装 Visual Studio,为的就是链接器和原生库4。

3. 手写 Hello World:最小的一个 Rust 程序长什么样

跳过 Cargo,先徒手做一遍。约定:Rust 源文件以 .rs 结尾,文件名多个单词用下划线连(hello_world.rs)5。

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

编译运行:

$ rustc main.rs
$ ./main
Hello, world!

rustc main.rs 之后,目录里多出一个可执行文件(Windows 上是 main.exe 外加一个 .pdb 调试信息文件)6。逐行看这三行代码能学到三个本书从头用到尾的细节:

  1. fn main() 是程序的入口。 每个可执行的 Rust 程序,运行时第一个执行的函数就叫 main;括号里没有参数 (参数就是调用时传给函数的值),不返回东西。函数体用大括号 {} 包住, 左大括号约定跟在函数声明同一行。
  2. println! 后面那个感叹号表示:这是宏(macro),不是普通函数。 如果它是普通函数,就写作 println(没有 !)。宏是"写代码来生成代码"的那套办法,第 20 章才展开;现在只要记住:见到名字带 ! 的,就是在调宏,宏不总守函数的规矩7。
  3. 行尾的分号表示这个式子到此为止。 Rust 代码大多数行以 ; 结尾,后面讲语句与表达式时会再回来(第 3 章)。

一个对动态语言用户要紧的对比

如果你用 Ruby、Python、JavaScript 这类语言长大,可能不习惯"编译"和"运行"是两个分开的步骤。书里点明了 Rust 的取舍:Rust 是预先编译(ahead-of-time compiled)的语言——编译出可执行文件后,交给别人,别人机器上没装 Rust 也能跑;而 .rb、.py、.js 文件交出去,对方得先装对应的运行环境8。原书把话挑明:"语言设计里处处是权衡。"

这句"处处是权衡"不是客套,是这本书的暗线。你每学一个 Rust 特性,都可以问一句:它拿什么东西换了什么。这一章的权衡是:多一步编译,换一个能独立分发、不依赖对方环境的可执行文件。

4. Cargo:这一章真正的主角

4.1 Cargo 是什么、为什么人人都用它

Cargo 是 Rust 的构建系统兼包管理器9。三个词拆开:

词 意思 Cargo 替你做的事
构建系统 把源代码变成可执行文件的那套流程 调编译器、传参数、决定先编哪个后编哪个
包管理器 管"别人的代码"的工具 下载你声明依赖的库,并把那些库也编译好

书里的口径很直接:代码一复杂,要管的可选项和依赖一多,"让 Cargo 来协调构建就省事得多"10。

它管的那种"别人的代码"在 Rust 里有个专门名字:crate——这是 Rust 对代码包/库的称呼, Cargo.toml 里的 [dependencies] 段就是列 crate 的地方。这个词现在记住,第 7、14 章会把它彻底讲透。

4.2 cargo new:一个项目骨架里有什么

$ cargo new hello_cargo
$ cd hello_cargo

这一条命令建出一个目录,里面有两样东西一个文件夹:Cargo.toml、src/main.rs,外加帮你初始化的 Git 仓库(在已有 Git 仓库里运行则不会)11。目录布局本身就是一条约定:

hello_cargo/
├── Cargo.toml      ← 项目的"户口本":名字、版本、用哪版 Rust、依赖谁
├── src/
│   └── main.rs     ← 代码只住在这里
└── target/         ← cargo build 之后出现:编译产物全在这(以后)

顶层目录只放 README、许可证、配置文件这些"与代码无关"的东西;源码一律进 src。 书里的原话是"每样东西都有它的位置,每样东西都在它的位置上"——这条约定让任何人拿到一个 Cargo 项目都知道往哪看12。

Cargo.toml 的内容(这就是 cargo new 生成的原样):

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

[dependencies]
  • 文件格式是 TOML,一种刻意做得"一看就懂"的配置格式。
  • [package] 开头的一段在声明:这是个包,名字叫 hello_cargo,版本 0.1.0。
  • edition = "2024" 指定这个项目按 Rust 2024 版(edition,约每三年发一版)的语法和习惯来编译——这个键的含义附录 E 专讲,现在只需知道:它存在,而且新项目的默认值就是 202413。
  • [dependencies] 是空段:这个项目谁也不依赖。第 2 章马上往里填第一个外部 crate。

4.3 build / run / check:三个命令各干什么

主线例子从空项目走到第一次 cargo run,书里有完整的真实输出,一步一步看:

第 ① 步:cargo build(第一次)

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

产物不在当前目录,而在 target/debug/hello_cargo。注意 dev 与 unoptimized 字样:默认编出来的是调试版——不做优化、编译快、跑得慢,专为"改十遍跑一遍"的循环设计14。

第 ② 步:cargo run(没改代码时)

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

关键在 in 0.0 secs:Cargo 发现文件没动过,跳过编译直接跑。 如果你刚改过源代码,同样的命令会先出现 Compiling ... 那一行再跑15。 所以日常流程是 cargo run 一把梭,不用记 build 之后那一长串路径。

第 ③ 步:cargo check(只查不编)

$ cargo check
    Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

check 只验证"代码能不能编译过",不产出可执行文件。为什么有人要这个?因为跳过生成可执行文件那一步,它比 build 快得多——写代码的过程中隔几分钟查一次"还编得过吗",用 check;真要跑程序时才 build 或 run16。

第 ④ 步:cargo build --release

$ cargo build --release
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished release [optimized] target(s) in 2.85 secs

产物落在 target/release/。开优化的版本编译慢、跑得快——所以书里特意叮嘱:量程序跑得有多快时,一定要编 release 版再量,拿 debug 版测出来的数字不是这个程序的真实速度17。

第 ⑤ 步:Cargo.lock 悄悄出现

第一次 cargo build 后项目顶层还会多一个 Cargo.lock。它记录这个项目依赖的确切版本,不需要你手动改,Cargo 全权管理18。项目没有依赖时这个文件近乎空壳,第 2 章加了外部 crate 之后它就变得要紧了。

4.4 回头看:两条路线的分水岭

现在回到第 1 节那张对照图。手写的 rustc main.rs 和 Cargo 到底差在哪?

差的不在"能不能编出同一个程序"——在"项目长大之后谁还管得动"。 一个文件、零依赖,两者等价;一旦变成十几个文件、依赖三五个外部库, "下载哪些版本、按什么顺序编译、参数怎么传"全变成手工活,这就是 Cargo 存在的理由19。 另外 Cargo 的命令在所有操作系统上长得一样——这也是书从这里起不再区分 Linux/macOS/Windows 写法的原因20。

5. 作者的判断与证据

这一章基本没有需要辩护的主张,只有两处态度值得标出来:

  • "绝大多数 Rust 项目都用 Cargo"——这是社区事实陈述,证据是它成了全书的默认前提1。
  • "设计里处处是权衡"——编译/运行分两步换可分发可执行文件,这是作者主动点破的语言设计观,后面所有章节都能见到这个视角8。

判断(我们的,不是书里的): 这一章教的最有价值的东西其实不是命令,而是目录约定即接口。 src/ 放代码、Cargo.toml 写元数据、target/ 装产物——约定一旦统一,任何工具、任何 CI、 任何新队友都能零成本接手一个陌生项目。Rust 生态后来的强协作性,第一层地基就浇在这里。 如果错,会错在: 约定人人遵守靠的是工具默认生成 + 社区共识,若有大批项目偏离默认布局, 这条"统一接口"的论断就要打折——但就本书成书时的生态现状看,偏离者寥寥。

6. 边界与局限

  • 版本敏感:安装命令、IDE 集成指引这类内容随时间失效最快。本拆解依据的是 2026-10 收录的第三版文本,实际安装请以官网为准。
  • 这一章不教任何语言机制——变量、类型、函数一概没有。那是第 3 章的活;想先看完整的"写程序"流程,第 2 章的猜数字游戏一章看完再回来补课也行(这是原书自己给的路径建议)。
  • Cargo.toml 的全部能力(profiles、feature、workspace……)这里只露一角,第 14 章专讲。

7. 可带走的

  1. 装 Rust 用 rustup;rustc --version 验证;rustup update 升级。
  2. 任何 Rust 可执行程序都从 fn main() 开始;名字! 是宏,名字 是函数。
  3. Rust 预先编译:产物是可以直接分发、对方无需装环境的可执行文件。
  4. 新项目一律 cargo new;源码进 src/,Cargo.toml 是项目的户口本。
  5. 日常三命令:cargo run(边改边跑)、cargo check(最快地知道还编不编得过)、cargo build --release(要性能时)。
  6. debug 版快编译慢运行,release 版反过来;测性能必须测 release 版。
  7. Cargo.lock 记依赖的确切版本,别手改,交给 Cargo。
  8. edition = "2024" 指定按 2024 版语言习惯编译,新项目默认值(附录 E 讲机制)。

8. 原文地图

主题 原书章 原文位置
rustup 安装与验证 Chapter 1: Getting Started text/08-ch01-chapter-1-getting-started.txt:19(搜「latest stable version」) · text/08-ch01-chapter-1-getting-started.txt:74(搜「rustc --version」)
Hello World 程序解剖 同上 text/08-ch01-chapter-1-getting-started.txt:194(搜「Anatomy of a Rust Program」)
宏与感叹号 同上 text/08-ch01-chapter-1-getting-started.txt:223(搜「Rust macro」)
预先编译语言 同上 text/08-ch01-chapter-1-getting-started.txt:272(搜「ahead-of-time compiled language」)
Cargo 是什么 同上 text/08-ch01-chapter-1-getting-started.txt:284(搜「build system and package manager」)
Cargo.toml 逐行 同上 text/08-ch01-chapter-1-getting-started.txt:329(搜「Open Cargo.toml」)
build / run / check 对比 同上 text/08-ch01-chapter-1-getting-started.txt:377(搜「cargo build」) · text/08-ch01-chapter-1-getting-started.txt:418(搜「cargo check」)
release 构建与基准测试告诫 同上 text/08-ch01-chapter-1-getting-started.txt:447(搜「cargo build --release」)


  1. 出处:「Chapter 1: Getting Started」第 294 段(text/08-ch01-chapter-1-getting-started.txt:294,搜「vast majority of Rust projects」)。原话:绝大多数 Rust 项目都用 Cargo,本书其余部分假定读者也用。 ↩↩

  2. 出处:「Chapter 1: Getting Started」第 74 段(text/08-ch01-chapter-1-getting-started.txt:74,搜「rustc --version」)。 ↩

  3. 出处:「Chapter 1: Getting Started」第 49 段(text/08-ch01-chapter-1-getting-started.txt:49,搜「You will also need a linker」)。 ↩

  4. 出处:「Chapter 1: Getting Started」第 64 段(text/08-ch01-chapter-1-getting-started.txt:64,搜「prompted to install Visual Studio」)。 ↩

  5. 出处:「Chapter 1: Getting Started」第 161 段(text/08-ch01-chapter-1-getting-started.txt:161,搜「always end with」)。 ↩

  6. 出处:「Chapter 1: Getting Started」第 245 段(text/08-ch01-chapter-1-getting-started.txt:245,搜「outputs a binary executable」)。 ↩

  7. 出处:「Chapter 1: Getting Started」第 223 段(text/08-ch01-chapter-1-getting-started.txt:223,搜「calls a Rust macro」)。 ↩

  8. 出处:「Chapter 1: Getting Started」第 272 段(text/08-ch01-chapter-1-getting-started.txt:272,搜「ahead-of-time compiled language」)。结尾的"处处是权衡"见同段(text/08-ch01-chapter-1-getting-started.txt:277,搜「Everything is a trade-off」)。 ↩↩

  9. 出处:「Chapter 1: Getting Started」第 284 段(text/08-ch01-chapter-1-getting-started.txt:284,搜「build system and package manager」)。 ↩

  10. 出处:「Chapter 1: Getting Started」第 460 段(text/08-ch01-chapter-1-getting-started.txt:460,搜「much easier to let Cargo coordinate the build」)。 ↩

  11. 出处:「Chapter 1: Getting Started」第 319 段(text/08-ch01-chapter-1-getting-started.txt:319,搜「two files and one directory」)与第 321 段(text/08-ch01-chapter-1-getting-started.txt:321,搜「initialized a new Git repository」)。 ↩

  12. 出处:「Chapter 1: Getting Started」第 362 段(text/08-ch01-chapter-1-getting-started.txt:362,搜「inside the src directory」)。 ↩

  13. 出处:「Chapter 1: Getting Started」第 334 段(text/08-ch01-chapter-1-getting-started.txt:334,搜「edition =」)。edition 键的说明见第 347 段(text/08-ch01-chapter-1-getting-started.txt:347,搜「Appendix E」)。 ↩

  14. 出处:「Chapter 1: Getting Started」第 380 段(text/08-ch01-chapter-1-getting-started.txt:380,搜「creates an executable file in target/debug」)。 ↩

  15. 出处:「Chapter 1: Getting Started」第 407 段(text/08-ch01-chapter-1-getting-started.txt:407,搜「hadn’t changed」)。 ↩

  16. 出处:「Chapter 1: Getting Started」第 427 段(text/08-ch01-chapter-1-getting-started.txt:427,搜「skips the step of producing an executable」)。 ↩

  17. 出处:「Chapter 1: Getting Started」第 447 段(text/08-ch01-chapter-1-getting-started.txt:447,搜「cargo build --release」)与第 454 段(text/08-ch01-chapter-1-getting-started.txt:454,搜「benchmarking your code」)。 ↩

  18. 出处:「Chapter 1: Getting Started」第 390 段(text/08-ch01-chapter-1-getting-started.txt:390,搜「keeps track of the exact versions」)。 ↩

  19. 出处:「Chapter 1: Getting Started」第 460 段(text/08-ch01-chapter-1-getting-started.txt:460,搜「programs grow to multiple files」)。 ↩

  20. 出处:「Chapter 1: Getting Started」第 442 段(text/08-ch01-chapter-1-getting-started.txt:442,搜「same no matter which operating system」)。 ↩