【Rust】Rust 编程之道
Rust 是什么
Rust 是一门系统编程语言,由 Mozilla Research 主导开发,2015 年发布 1.0 版本。它的核心设计目标是:在保证内存安全和线程安全的前提下,提供与 C/C++ 同级别的运行时性能。
Rust 通过三个核心机制实现这一目标:
- 所有权(Ownership):每一块内存有且仅有一个所有者,所有者在离开作用域时自动释放内存。这是 Rust 在编译期消灭悬垂指针、双重释放、use-after-free 等内存bug的根本原因。
- 借用(Borrowing):允许多个不可变引用或一个可变引用,但不能同时。这从类型系统层面杜绝了竞态条件,是并发安全的基石。
- 生命周期(Lifetime):编译器追踪每一个引用的有效期,确保引用不会比被引用的数据活得更久。
Rust 是静态类型语言,所有类型在编译期确定。Rust 也支持类型推断,在大量场景下无需显式标注类型。Rust 没有垃圾回收器(GC),没有运行时开销,却通过编译期的静态分析实现了 GC 级别的安全保证。
Rust 怎么诞生的
2006 年,软件开发人员 Graydon Hoare 在 Mozilla 工作期间,将 Rust 作为个人项目启动。根据《麻省理工科技评论》的采访,Rust 的灵感来自 Hoare 公寓楼里一部坏掉的电梯。当时电梯操作系统的软件崩溃了,Hoare 明白,类似的问题通常来自程序内存管理的问题。通常,这类设备的软件都是用 C 或 C++ 编写的,但这些语言需要大量的手动内存管理,很容易导致错误,造成系统崩溃。因此,Hoare 开始着手研究如何创建一种既紧凑又无内存错误的编程语言。
后来,他向一位经理展示了这个项目——这也让 Mozilla 在 2009 年赞助了这个项目,作为将 Rust 语言纳入一项实验性浏览器引擎开发(Servo)的长期努力的一部分。2010 年,Mozilla Research 正式宣布了 Rust 项目,并将源代码作为开源项目向公众发布。经过几年的开发,Rust 达到了稳定和成熟的状态,于 2015 年 5 月 15 日发布了 Rust 1.0。这一里程碑标志着 Rust 已经为生产做好了准备。
自 1.0 发布以来,Rust 的受欢迎程度和使用率呈爆炸式增长。2016 年起,Rust 连续多年在 Stack Overflow 开发者调查中被票选为「最受喜爱的编程语言」。微软 Windows 团队用 Rust 重写了核心系统库;Linux 内核从 6.1 版本开始正式支持 Rust 作为第二语言;Android 团队将 Rust 引入用户空间和内核模块开发。在科技巨头之外,Rust 还拥有一个充满活力的开发者社区——「Rustaceans」,他们致力于让 Rust 成为一种活跃的协作体验。
Rust 核心特点
1. 内存安全,无需垃圾回收
Rust 通过所有权系统和借用检查器在编译期保证内存安全,不需要垃圾回收器在运行期追踪和回收内存。这意味着:
- 无悬垂指针:编译器禁止引用已被释放的内存
- 无双重释放:所有权规则保证每块内存只被释放一次
- 无空指针解引用:Rust 使用
Option<T>类型代替空指针,编译器强制检查 - 无缓冲区溢出:数组和切片访问在运行时做边界检查(或通过迭代器在编译期保证安全)
// 这段代码无法通过编译——Rust 在编译期就捕获了 use-after-move 错误
let s1 = String::from("hello");
let s2 = s1; // 所有权从 s1 转移到 s2
println!("{}", s1); // 编译错误:s1 已被移动,无法使用2. 安全的并发编程
Rust 的类型系统将并发安全的保证从运行时提前到了编译期。Send 和 Sync Trait 标记了哪些类型可以安全地在线程间传递或共享。借用规则(一个可变引用或多个不可变引用)从类型层面杜绝了数据竞争。
use std::thread;
let data = vec![1, 2, 3];
// 错误:编译器阻止了数据竞争!
// 如果多个线程同时可变访问 data,编译器会拒绝编译
thread::spawn(move || {
println!("{:?}", data);
}).join().unwrap();Rust 的并发模型涵盖了主流并发原语:Mutex、RwLock、Condvar、Channel、Atomic 类型,以及 async/await 异步运行时。
3. 零成本抽象
Rust 的抽象(泛型、Trait、闭包、迭代器等)在编译后生成的机器码与手写的低级代码性能相当。这是通过单态化(monomorphization)实现的一一编译器为每个具体类型生成一份特化的代码副本,使得泛型代码在运行时没有任何虚函数调用或装箱开销。
// 这两行代码生成的机器码完全相同
let sum: i32 = (0..1000).sum(); // 迭代器抽象
let mut sum = 0;
for i in 0..1000 { sum += i; } // 手写循环4. 强大的类型系统
- 代数数据类型(ADT):枚举可以携带数据,配合模式匹配实现穷尽性检查
- Trait 系统:类似 Haskell 的 typeclass,支持静态分发和动态分发
- 泛型:支持泛型参数的类型约束和生命周期约束
- 模式匹配:
match表达式必须处理所有可能的模式,编译器会检查遗漏的分支
5. Cargo 包管理器和生态系统
Cargo 是 Rust 内置的构建系统和包管理器。Cargo.toml 声明依赖,cargo build 自动下载和编译,cargo test 运行测试,cargo doc 生成文档。crates.io 是 Rust 的官方包仓库,截至 2025 年已有超过 16 万个 crate。
Rust 是第一种拥有标准包管理器的系统编程语言。在此之前,C/C++ 开发者需要手动处理依赖、构建配置和跨平台兼容性。Cargo 从根本上改变了系统编程的工作流。
教程全览:23 章覆盖 Rust 体系
本教程以 Jim Blandy、Jason Orendorff 和 Leonora F. S. Tindall 合著的 《Programming Rust》(第 2 版,O'Reilly 出版) 为主线,结合官方文档和实践经验,从零开始系统学习 Rust。
| 章节 | 标题 | 所属主题 |
|---|---|---|
| 基础篇:类型与内存 | ||
| 1 | Why Rust — 为什么选择 Rust | 动机与背景 |
| 2 | Tour of Rust — Rust 速览 | 全景概览 |
| 3 | Basic Types — 基本类型 | 类型系统 |
| 4 | Ownership & Moves — 所有权与移动 | 内存管理 |
| 5 | References & Borrowing — 引用与借用 | 内存管理 |
| 6 | Expressions & Control Flow — 表达式与控制流 | 语言基础 |
| 进阶篇:核心抽象 | ||
| 7 | Error Handling — 错误处理 | 工程实践 |
| 8 | Crates & Modules — 包与模块 | 工程实践 |
| 9 | Structs — 结构体 | 类型系统 |
| 10 | Enums & Patterns — 枚举与模式匹配 | 类型系统 |
| 11 | Traits & Generics — Trait 与泛型 | 抽象机制 |
| 12 | Operator Overloading — 运算符重载 | 抽象机制 |
| 13 | Utility Traits — 实用 Trait | 抽象机制 |
| 高级篇:函数式与集合 | ||
| 14 | Closures — 闭包 | 函数式编程 |
| 15 | Iterators — 迭代器 | 函数式编程 |
| 16 | Collections — 集合类型 | 数据结构 |
| 17 | Strings & Text — 字符串与文本 | 数据处理 |
| 18 | I/O — 输入输出 | 系统交互 |
| 系统编程篇:并发与底层 | ||
| 19 | Concurrency — 并发编程 | 并发 |
| 20 | Async Programming — 异步编程 | 并发 |
| 21 | Unsafe Code — 不安全代码 | 底层 |
| 22 | FFI — 外部函数接口 | 底层 |
| 23 | Macros — 宏 | 元编程 |
为什么选《Programming Rust》而非官方手册
Rust 官方有两本经典书籍:《The Rust Programming Language》(TRPL,俗称「The Book」)和《Rust by Example》。它们都非常优秀,适合入门。但本教程选择《Programming Rust》作为主线,原因如下:
| 维度 | The Book (TRPL) | Programming Rust |
|---|---|---|
| 目标读者 | 编程初学者至中级 | 有经验的系统程序员 |
| 深度 | 概念介绍 + 基础示例 | 深入原理 + 大规模实例 |
| 视角 | 「Rust 是什么」 | 「Rust 为什么这样设计」 |
| 篇幅 | 约 560 页 | 约 735 页 |
| 代码示例 | 简短、聚焦单一概念 | 完整的可运行程序 |
| C/C++ 对照 | 较少 | 频繁对比 C/C++ 中的对等做法 |
| 内存模型 | 简要说明 | 深入栈/堆布局、指针表示 |
如果你符合以下任一条件,本教程尤其适合你:
- 有 C/C++ 基础,想理解 Rust 如何在保证安全的同时不牺牲性能
- 关注系统编程:嵌入式、操作系统、数据库、网络服务
- 不满足于「怎么用」,还想知道「为什么这样设计」
- 希望通过 Rust 深入理解计算机底层:内存布局、并发模型、ABI
本教程保持了原著的深度和系统视角,同时针对中文读者做了语言上的优化和补充。每一章末尾都有要点总结,方便回顾。
前置知识
本教程假定读者具备以下基础:
- 至少一门编程语言的使用经验(C/C++/Python/Java/Go 均可)
- 基本的计算机组成原理知识:栈与堆、指针、CPU 与内存
- 命令行操作:能够在终端中执行
cargo命令
如果你是编程初学者,建议先阅读《The Rust Programming Language》,完成 Rustlings 练习,再回到本教程深入学习。
准备好踏上 Rust 的旅程了吗?让我们从「为什么是 Rust」开始。