Rust 学习教程
这是一本从示例代码出发的 Rust 学习笔记,也是一份配套 src/study 示例模块的教程索引。每个章节都对应可运行的代码演示,你可以在阅读文档的同时,直接运行、修改、调试对应的代码,在实践中理解 Rust。
Rust 学习模式
学习 Rust 时,一个常见的误区是一上来就死磕语法细节。Rust 的语法体系庞大且相互关联,这些语法对初学者来说都很难一次性吃透。
推荐的节奏是两遍法:
-
第一遍:快速通读,留下印象。 不需要理解每一个细节,重点是知道“有这个语法、它大概用来干什么“。比如看到
match,知道它是 Rust 中的模式匹配,能处理Option和Result;看到&和&mut,知道这是在标记借用关系即可。 -
第二遍:从复刻示例代码出发,边写边学。 把
src/study中的示例代码亲手敲一遍(不要复制粘贴),在复刻过程中你会自然地遇到编译错误——这正是 Rust 学习的精华时刻。Rust 编译器以友好著称,它的报错信息会告诉你:- 哪里出了问题
- 为什么会出问题
- 甚至建议你怎么修改
认真阅读每一条编译错误,理解编译器在说什么,这个过程本身就是最好的学习。遇到看不懂的概念,再回到文档对应章节精读,带着问题学远比被动阅读有效。
简单来说:先建立语法→功能的心智地图,再用编译器的反馈来校准理解。
Rust 重点学习内容
1. 内存管理(第四章的四个部分)
这是 Rust 区别于其他主流语言的核心设计,也是学习曲线最陡的部分:
- 所有权机制:Rust 如何在不使用 GC 的情况下保证内存安全?移动语义、借用规则、引用的生命周期约束——这套规则是 Rust 的“宪法“,理解了所有权,就理解了 Rust 的一半。
- 智能指针:
Box<T>、Rc<T>、Arc<T>——当所有权规则无法满足灵活的数据共享需求时,智能指针提供了受控的“弹性空间“。 - 内部可变性:
Cell<T>和RefCell<T>让你在持有不可变引用时也能修改数据,把借用检查从编译期推迟到运行时。 - 生命周期:显式生命周期标注是 Rust 的特色——它把对象之间的引用关系显式化,让你(和编译器)能清晰地看到“谁依赖谁、谁比谁活得长“。
2. 错误处理:Option、Result 与 match
Rust 没有异常机制,而是通过 Option<T> 和 Result<T, E> 将错误作为类型的一部分进行编码。配合 match 模式匹配,Rust 强制你在编译期就处理所有可能的错误路径——不会有“忘记 try-catch 导致运行时崩溃“的问题。这是 Rust 写出健壮代码的根基,详见第五章:返回值和错误处理。
3. Trait 体系
Trait 是 Rust 中定义和约束行为的核心机制。它既是接口,也是泛型约束,还能实现动态分发。理解 Trait 才能写出泛型、灵活、可组合的 Rust 代码。详见第七章:trait 特征。
从 GC 语言转向 Rust 需要转变的两个思维
如果你之前主要使用 Java、Go、Python、JavaScript 等带垃圾回收(GC)的语言,Rust 要求你在以下两个方面主动转变思维:
思维一:关注变量的内存位置——堆还是栈?
GC 语言中,你几乎不需要关心一个变量分配在堆上还是栈上——运行时帮你管理一切。但在 Rust 中,内存位置直接影响你的代码写法:
- 栈上数据:大小固定、生命周期确定,直接使用即可,编译器帮你搞定。
- 堆上数据:大小动态、需要共享或延长生命周期,你得显式使用
Box、Rc、Arc等智能指针来管理。
每当你声明一个变量时,试着问自己:这个数据的大小在编译期能确定吗?它的生命周期需要超出当前作用域吗?它需要被多处共享吗?——这些问题的答案决定了你应该把它放在栈上还是堆上,以及该用什么类型来承载它。
思维二:从对象生命周期的角度设计程序
GC 语言中,对象的生命周期是模糊的——只要还有引用,它就活着;引用没了,GC 在某个不确定的时刻回收它。你不需要、也很难精确掌控一个对象“什么时候死“。
Rust 则完全不同。所有权的转移、引用的有效期、drop 的调用时机——一切都是确定的。你需要养成一个习惯:在设计程序时,先想清楚每个关键数据的“生老病死“。谁负责创建它?谁持有它?它在什么时候、因为什么被释放?这种思维方式的转变一开始会很不适应,但一旦内化,你写出的代码会比 GC 时代的代码更加可靠和可预测。
从 C++ 转向 Rust 需要转变的一个关键思维
C++ 程序员对 Rust 的内存管理思想(RAII、确定性析构)并不陌生,但有一个核心差异需要主动适应:
C++ 中普通值的默认语义更偏向拷贝,而 Rust 对非 Copy 类型的默认语义是移动。
在 C++ 中,很多普通值赋值或传参时默认会发生拷贝;想表达“我愿意把资源转走”时,通常需要显式调用 std::move。在 Rust 中恰恰相反:没有实现 Copy 的类型赋值和传参默认就是移动——所有权直接转移,原变量立刻失效。只有实现了 Copy trait 的类型(基本是简单的标量类型)才会自动拷贝。
这个差异意味着:C++ 程序员在 Rust 中需要反向管理默认行为——在 C++ 中你主动决定“什么时候 move“,在 Rust 中你主动决定“什么时候 clone“。如果你发现自己在到处写 .clone(),那往往是一个信号:你的所有权设计可能需要重新审视。
本书结构
教程共十六章,从基础语法到高级异步编程,覆盖了 Rust 的主要知识领域:
| 章节 | 内容 | 对应代码 |
|---|---|---|
| 第一章 | 基础语法 | src/study/base_syntax.rs |
| 第二章 | Cargo 构建系统 | - |
| 第三章 | 泛型 | src/study/generic.rs |
| 第四章 | Rust 内存管理 | 4 个子章节均配有示例代码 |
| 第五章 | 返回值和错误处理 | src/study/return_handle.rs |
| 第六章 | 结构体 | src/study/struct_demo.rs |
| 第七章 | trait 特征 | src/study/trait_demo.rs 等 |
| 第八章 | 模块系统 | - |
| 第九章 | 闭包和函数 | src/study/closure_demo.rs |
| 第十章 | 容器 | src/study/collections.rs |
| 第十一章 | 面向对象 | src/study/oop_demo.rs |
| 第十二章 | 宏 | src/study/macro_rules_demo.rs 等 |
| 第十三章 | 并发编程 | 4 个子章节均配有示例代码 |
| 第十四章 | 文件 IO | src/study/file_io_demo.rs |
| 第十五章 | 网络 IO | src/study/network_io_demo.rs |
| 第十六章 | async 编程 | 3 个子章节均配有示例代码 |
阅读建议:前三章夯实基础后,第四章(内存管理)是全书最重要的部分,建议多花时间精读并动手调试代码。之后五到七章补齐类型系统,再根据兴趣和需求选择后续章节深入。