第零章:Rust 全景概览 —— 从 Web 到 Systems 的思维转变
第零章:Rust 全景概览 —— 从 Web 到 Systems 的思维转变
本章目标
- 理解为什么 TypeScript/JavaScript 开发者应该学习 Rust
- 了解 Rust 的发展历程与设计哲学
- 掌握 Rust 与其他语言(Go/C++/TS/Python)的核心差异
- 建立 Web 开发概念 → Rust 概念的映射关系
- 理解所有权、借用、生命周期的直觉
- 了解 Rust 生态全景(Web/CLI/WASM/嵌入式/区块链)
- 预览本教程将构建的实战项目
- 规划完整的学习路线图
预计学习时间:60 - 90 分钟
0.1 为什么写这个教程?
0.1.1 一封写给 TS/JS 开发者的信
如果你是一位前端或全栈开发者,熟悉 TypeScript/JavaScript,用 React、Vue 或 Next.js 构建过 Web 应用,用 Node.js 或 Deno 写过后端服务 —— 那么这个教程就是为你量身打造的。
你可能已经注意到了:越来越多的前端工具正在用 Rust 重写。
JavaScript 生态中的 Rust 入侵
├── 🔧 构建工具
│ ├── SWC -- 替代 Babel,快 20 倍
│ ├── Turbopack -- 替代 Webpack,Vercel 出品
│ ├── Rspack -- 替代 Webpack,字节跳动出品
│ └── Rolldown -- 替代 Rollup,尤雨溪主导
├── 📦 包管理
│ └── pnpm -- 部分核心用 Rust 重写
├── 🎨 CSS
│ └── Lightning CSS -- 替代 PostCSS,快 100 倍
├── 🧹 代码质量
│ ├── Biome -- 替代 ESLint + Prettier
│ └── oxlint -- 替代 ESLint,快 50-100 倍
├── 📝 语言服务
│ └── rust-analyzer -- 本身就是 Rust 写的 LSP
└── 🌐 运行时
├── Deno -- 核心用 Rust 编写
└── Bun -- 核心用 Zig(类似思路)
为什么这些工具都选择了 Rust? 因为 JavaScript 在某些场景下确实太慢了。当你的 Webpack 构建需要 30 秒,而 Rspack 只要 1 秒的时候,你就知道性能差距有多大了。
但这不是你学 Rust 的唯一理由。
0.1.2 学 Rust 对 TS/JS 开发者的独特价值
1. 理解”底层到底发生了什么”
当你写 TypeScript 的时候,V8 引擎帮你做了太多事情:
// 你写的代码
const users = data.filter(u => u.active).map(u => u.name);
// V8 在背后做的事情(简化版):
// 1. 解析 JavaScript 代码为 AST
// 2. 生成字节码
// 3. JIT 编译为机器码
// 4. 为 data 数组分配堆内存
// 5. 为 filter 的回调函数创建闭包(分配内存)
// 6. 遍历数组,为每个通过 filter 的元素分配新数组空间
// 7. 为 map 的回调函数创建闭包(分配内存)
// 8. 再次遍历,为每个 name 字符串分配内存
// 9. 创建最终的数组对象
// 10. 之前的中间数组?等 GC 来回收……
在 Rust 中,你需要显式地思考这些问题 —— 而这恰恰让你成为更好的开发者。
2. 写更安全的代码
TypeScript 的类型系统已经比纯 JavaScript 安全很多了,但它有盲区:
// TypeScript 无法阻止的问题
// 1. 运行时空指针
const user = users.find(u => u.id === 999);
console.log(user.name); // 💥 运行时 TypeError: Cannot read property 'name' of undefined
// TypeScript 知道可能是 undefined,但你可以用 ! 绕过
// 2. 数据竞争
let count = 0;
await Promise.all([
fetch('/api/a').then(() => count++),
fetch('/api/b').then(() => count++),
]);
// count 的最终值是什么?在 JS 单线程中没问题,但概念上这是不安全的
// 3. 内存泄漏
const cache = new Map();
function processUser(user: User) {
cache.set(user.id, user); // 永远不会被 GC 回收
}
Rust 在编译期就阻止了这些问题。不是通过 lint 规则或最佳实践,而是通过语言本身的类型系统。
3. 打开新的职业赛道
掌握 Rust 意味着你可以:
- 为前端工具链贡献代码(SWC、Turbopack、Biome)
- 开发高性能 WebAssembly 模块
- 构建系统级工具和 CLI
- 进入区块链开发领域(Solana、Polkadot)
- 编写嵌入式/IoT 程序
- 参与云原生基础设施开发
0.1.3 我们的教学方法
我们不会像传统 Rust 教程那样从零开始讲变量和循环。相反,我们会持续地做概念映射:
你已经知道的(TS/JS) → 你将要学的(Rust)
─────────────────────────────────────────────
npm install → cargo add
package.json → Cargo.toml
node_modules/ → target/
tsconfig.json → Cargo.toml [profile]
interface User { } → struct User { }
type Result = A | B → enum Result { A, B }
try { } catch { } → Result<T, E> + ? 操作符
async/await → async/await(语法几乎一样!)
.map().filter() → .iter().map().filter()
class 继承 → Trait 组合
每当你在 Rust 中遇到新概念,我们会先找到你在 TS/JS 中已经熟悉的对应概念,然后从那个基础出发。
0.2 Rust 发展历程
0.2.1 起源故事
Rust 的诞生源于一个 Mozilla 工程师的个人挫败感。
Rust 时间线
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2006 ── Graydon Hoare 开始 Rust 作为个人项目
起因:他公寓的电梯软件崩溃了,
他想:"为什么我们还在用会崩溃的语言写关键系统?"
2009 ── Mozilla 开始赞助 Rust 开发
目标:为 Firefox 浏览器引擎提供更安全的语言
2010 ── Rust 首次公开亮相
当时的 Rust 和今天差别很大(有 GC、有绿色线程)
2012 ── Rust 0.1 发布
开始去掉 GC,引入所有权系统
2015 ── Rust 1.0 稳定版发布 🎉
承诺:1.0 之后永远向后兼容
2016 ── 第一次获得 Stack Overflow "最受喜爱语言" 🏆
此后连续 8 年蝉联第一
2018 ── Rust 2018 Edition
引入 async/await、模块系统改进
2020 ── Rust Foundation 成立
AWS、Google、华为、微软、Mozilla 共同发起
2021 ── Rust 2021 Edition
闭包改进、数组 IntoIterator
2023 ── Linux 内核正式引入 Rust 🐧
Linus Torvalds:"我认为 Rust 可以用于内核开发"
2024 ── Rust 在 AI/ML 领域快速增长
Hugging Face 的 Candle、Burn 框架
2025 ── Rust 2024 Edition
生态持续成熟,async trait 稳定化
Windows 内核也开始采用 Rust
0.2.2 一个重要的设计决定
Rust 早期版本(0.x 时代)其实有垃圾回收器(GC)。但团队做了一个大胆的决定:去掉 GC,用所有权系统来管理内存。
这就像如果 TypeScript 团队决定去掉 any 类型一样激进 —— 短期内让语言更难用,但长期带来了巨大的好处。
💡 TS 类比:你可以把 Rust 去掉 GC 类比为 TypeScript 把 strict: true 设为默认。是的,一开始会多写很多类型标注,但 bug 也少了很多。Rust 的所有权系统就是这种思路的极致版本。
0.2.3 谁在用 Rust?
使用 Rust 的公司和项目
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔵 微软 (Microsoft)
- Windows 内核部分组件用 Rust 重写
- Azure IoT Edge
- "我们认为 Rust 是编写安全系统软件的最佳选择"
🟢 谷歌 (Google)
- Android 操作系统(部分 HAL 和系统组件)
- Chromium 项目开始引入 Rust
- Fuchsia 操作系统
🟠 亚马逊 (AWS)
- Firecracker(Lambda 和 Fargate 的虚拟化引擎)
- Bottlerocket(容器优化的 Linux 发行版)
- S3 的部分组件
⬛ Meta (Facebook)
- Mononoke(大规模源代码管理)
- Diem 区块链(原 Libra)
🔴 字节跳动
- Rspack(Webpack 替代品)
- 部分后端服务
🟣 Cloudflare
- 网络边缘计算基础设施
- Pingora(替代 Nginx 的反向代理)
🔵 Discord
- 从 Go 迁移到 Rust(读状态服务)
- "延迟从 P99 几百毫秒降到个位数毫秒"
💚 Vercel
- Turbopack(下一代打包工具)
- SWC(JavaScript/TypeScript 编译器)
🔶 Shopify
- YJIT(Ruby JIT 编译器,用 Rust 编写)
🌐 更多
- Mozilla (Firefox, Servo)
- Dropbox(文件同步引擎)
- npm(注册表服务)
- 1Password(密码管理器核心)
- Figma(多人协作引擎)
0.3 Rust vs 其他语言:全方位对比
0.3.1 Rust vs TypeScript
这是你最关心的对比。让我们深入看看。
类型系统对比:
// ====== TypeScript ======
// TypeScript 的类型系统是"结构化类型"(Structural Typing)
// 也叫"鸭子类型":如果形状匹配,就认为类型匹配
interface Printable {
print(): void;
}
class Dog {
print() { console.log("Woof"); }
}
class Cat {
print() { console.log("Meow"); }
}
// Dog 和 Cat 都没有 implements Printable
// 但因为它们都有 print() 方法,所以可以当 Printable 用
function printThing(p: Printable) { p.print(); }
printThing(new Dog()); // ✅ 没问题
printThing(new Cat()); // ✅ 也没问题
// ====== Rust ======
// Rust 的类型系统是"名义类型"(Nominal Typing)
// 你必须显式地声明"我实现了这个 trait"
trait Printable {
fn print(&self);
}
struct Dog;
struct Cat;
// 必须显式 impl
impl Printable for Dog {
fn print(&self) { println!("Woof"); }
}
impl Printable for Cat {
fn print(&self) { println!("Meow"); }
}
// 使用 trait bound
fn print_thing(p: &dyn Printable) { p.print(); }
// 或者静态分发(零成本抽象,编译期确定具体类型)
fn print_thing_static(p: &impl Printable) { p.print(); }
💡 TS 类比:
- TypeScript 的
interface≈ Rust 的trait - 但 TS 是”如果你长得像鸭子就是鸭子”,Rust 是”你必须正式登记为鸭子”
- Rust 的方式更严格,但也更明确 —— 你永远知道一个类型实现了哪些行为
空值处理对比:
// ====== TypeScript ======
// null/undefined 是"十亿美元的错误"
// TypeScript 用 strictNullChecks 来缓解,但无法完全消除
function findUser(id: number): User | undefined {
return users.find(u => u.id === id);
}
const user = findUser(999);
// 如果你忘了检查 undefined...
console.log(user.name); // 💥 运行时崩溃
// 即使开启 strictNullChecks,你也可以用 ! 绕过
console.log(user!.name); // TypeScript 不再警告,但运行时依然可能崩溃
// ====== Rust ======
// Rust 没有 null。句号。
// 用 Option<T> 表示"可能没有值"
fn find_user(id: u32) -> Option<User> {
users.iter().find(|u| u.id == id).cloned()
}
let user = find_user(999);
// 你不可能忘记处理"没有值"的情况
// 因为 Option<User> 和 User 是完全不同的类型!
// println!("{}", user.name); // ❌ 编译错误!Option<User> 没有 name 字段
// 你必须显式处理
match user {
Some(u) => println!("{}", u.name), // 有值的情况
None => println!("用户不存在"), // 没有值的情况
}
// 或者用更简洁的方式
if let Some(u) = user {
println!("{}", u.name);
}
// 或者提供默认值
let name = user.map(|u| u.name).unwrap_or("匿名用户".to_string());
💡 TS 类比:
Option<T>≈T | undefined,但你不可能忘记处理undefined的情况- 没有
!非空断言操作符(好吧有.unwrap(),但它会 panic,而且代码审查时会被指出来)
错误处理对比:
// ====== TypeScript ======
// try/catch 是"我希望你记得处理错误"
async function fetchUser(id: number): Promise<User> {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
// 调用者可能忘记 try/catch
const user = await fetchUser(999); // 💥 如果出错,异常会一直冒泡
// ====== Rust ======
// Result<T, E> 是"你必须处理错误"
async fn fetch_user(id: u32) -> Result<User, reqwest::Error> {
let user = reqwest::get(format!("/api/users/{}", id))
.await? // ? 操作符:如果出错,提前返回错误
.json::<User>()
.await?;
Ok(user)
}
// 调用者也必须处理
match fetch_user(999).await {
Ok(user) => println!("找到用户: {}", user.name),
Err(e) => eprintln!("请求失败: {}", e),
}
// 或者用 ? 继续向上传播
let user = fetch_user(999).await?; // 如果出错,当前函数也返回 Err
💡 TS 类比:
Result<T, E>≈ 如果 TypeScript 强制你每个 async 函数都写 try/catch?操作符 ≈ 自动 throw,但是是类型安全的
性能对比:
操作 TypeScript (Node.js) Rust
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
JSON 解析 (1MB) ~15ms ~2ms
HTTP 服务 (QPS) ~30,000 ~200,000+
正则匹配 (100万次) ~800ms ~50ms
文件读取 (1GB) ~2s ~0.5s
内存占用 (Hello World) ~40MB ~1MB
启动时间 ~100ms ~1ms
二进制大小 需要 Node.js 运行时 ~5MB 独立可执行文件
⚠️ 以上数据为大致量级对比,实际性能取决于具体场景和优化程度。
0.3.2 Rust vs Go
Go 和 Rust 经常被拿来对比,因为它们都是现代系统编程语言。但它们的设计哲学截然不同。
Go Rust
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
设计哲学 简单、实用、快速上手 安全、高性能、零成本抽象
学习曲线 平缓(1-2 周即可上手) 陡峭(1-2 月才能顺畅)
内存管理 GC(垃圾回收) 所有权系统(无 GC)
并发模型 Goroutine(轻量级线程) async/await + 线程
错误处理 if err != nil { } Result<T, E> + ?
泛型 有(Go 1.18+) 有(更强大)
空值安全 有 nil(不安全) Option<T>(安全)
编译速度 极快(秒级) 较慢(分钟级)
运行时 较小(~10MB) 无运行时(~1MB)
适合场景 微服务、DevOps 工具 系统编程、高性能服务
代表项目 Docker, Kubernetes, Hugo Servo, ripgrep, Deno
类比 "编程语言界的 IKEA" "编程语言界的手工匠"
💡 选择建议:
- 如果你的目标是快速开发微服务 → Go
- 如果你需要极致性能或者无 GC → Rust
- 如果你想深入理解计算机系统 → Rust
- 如果你是团队合作,需要快速上手 → Go
一个经典的对比 —— JSON 反序列化:
// ====== Go ======
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
data := []byte(`{"name": "Alice", "age": 30}`)
var user User
err := json.Unmarshal(data, &user)
if err != nil {
log.Fatal(err) // 运行时错误
}
// user.Name 可能是空字符串 ""(Go 的零值)
// 你无法区分"字段不存在"和"字段值为空字符串"
}
// ====== Rust ======
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct User {
name: String,
age: u32,
// 可选字段用 Option 明确表示
email: Option<String>, // 可能没有
}
fn main() -> Result<(), serde_json::Error> {
let data = r#"{"name": "Alice", "age": 30}"#;
let user: User = serde_json::from_str(data)?;
// user.name 一定是有效的 String
// user.email 是 Option<String>,你必须处理 None 的情况
match user.email {
Some(email) => println!("邮箱: {}", email),
None => println!("没有提供邮箱"),
}
Ok(())
}
0.3.3 Rust vs C/C++
C/C++ 是系统编程的老牌王者,Rust 的目标就是在同一领域提供同等性能但更高安全性。
C/C++ Rust
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
历史 50+ 年 10+ 年
内存安全 手动管理(容易出错) 编译器保证
空指针 有(导致无数 bug) 没有(用 Option)
数据竞争 可能发生 编译器阻止
性能 极高 极高(几乎相当)
未定义行为 常见(UB 是 C++ 噩梦) 只在 unsafe 块中可能出现
包管理 CMake/Conan(混乱) Cargo(统一、优雅)
编译速度 C 快,C++ 慢 较慢
学习曲线 C 较低,C++ 极陡 陡峭但有回报
生态 巨大(几十年积累) 快速增长
适合场景 操作系统、驱动、嵌入式 同上 + Web 服务、CLI
经典的 C++ 内存错误 vs Rust 的编译期阻止:
// ====== C++ ======
// 悬垂指针(Use After Free)—— 安全漏洞的头号来源
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3};
int* p = &v[0]; // p 指向 v 的第一个元素
v.push_back(4); // 🔥 v 可能重新分配内存!
// p 现在指向已释放的内存!
std::cout << *p; // 💥 未定义行为!
// 可能打印垃圾值,可能崩溃,可能看起来正常
// 这就是 C++ 的恐怖之处
return 0;
}
// ====== Rust ======
fn main() {
let mut v = vec![1, 2, 3];
let p = &v[0]; // p 借用了 v 的第一个元素
v.push(4); // ❌ 编译错误!
// error[E0502]: cannot borrow `v` as mutable
// because it is also borrowed as immutable
//
// 编译器解释:你不能在 p 还在使用 v 的时候修改 v
// 因为 push 可能导致重新分配内存,让 p 变成悬垂指针
println!("{}", p); // 这行永远不会执行,因为编译就通不过
}
这就是 Rust 的核心价值:在编译期就阻止了 C/C++ 中最常见的安全漏洞。
0.3.4 Rust vs Python
Python Rust
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
类型系统 动态类型(+ type hints) 静态强类型
性能 慢(解释执行) 极快(编译执行)
内存管理 GC + 引用计数 所有权系统
并发 GIL 限制 真正的多线程
适合场景 数据科学、AI/ML、脚本 系统编程、高性能服务
性能差距 Rust 通常快 10-100 倍 —
互操作 PyO3 可以让 Rust 写 Python 扩展
有趣的是,越来越多的 Python 库底层用 Rust 重写来提升性能:
Python 生态中的 Rust
├── pydantic v2 -- 数据验证,Rust 核心
├── ruff -- Python linter,比 flake8 快 100 倍
├── uv -- Python 包管理器,比 pip 快 100 倍
├── polars -- DataFrame 库,比 pandas 快 10 倍
├── tokenizers -- Hugging Face 的分词器
└── cryptography -- Python 加密库的核心
0.3.5 综合对比总览
维度 TypeScript Go C++ Python Rust
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
性能 ★★☆☆☆ ★★★★☆ ★★★★★ ★☆☆☆☆ ★★★★★
安全性 ★★★☆☆ ★★★☆☆ ★★☆☆☆ ★★☆☆☆ ★★★★★
学习曲线 ★★★★☆ ★★★★★ ★★☆☆☆ ★★★★★ ★★☆☆☆
开发效率 ★★★★★ ★★★★☆ ★★☆☆☆ ★★★★★ ★★★☆☆
生态成熟度 ★★★★★ ★★★★☆ ★★★★★ ★★★★★ ★★★☆☆
并发能力 ★★☆☆☆ ★★★★★ ★★★★☆ ★★☆☆☆ ★★★★★
0.4 Web 开发概念 → Rust 概念映射
这是本章最重要的一节。我们建立一张完整的映射表,让你在后续学习中能快速找到”锚点”。
0.4.1 核心概念映射
| Web 开发概念 | Rust 对应概念 | 简要说明 |
|---|---|---|
npm / yarn / pnpm | cargo | 包管理器 + 构建工具 + 测试运行器(全合一!) |
package.json | Cargo.toml | 项目配置和依赖声明 |
node_modules/ | target/ | 编译产物和依赖缓存 |
npx | cargo install | 安装和运行 CLI 工具 |
| npm registry | crates.io | 包注册表 |
tsconfig.json | Cargo.toml 的 [profile] | 编译配置 |
.npmrc | ~/.cargo/config.toml | 全局配置 |
package-lock.json | Cargo.lock | 依赖锁定文件 |
0.4.2 语言特性映射
| TypeScript | Rust | 说明 |
|---|---|---|
let x = 5 | let x = 5 | 几乎一样!但 Rust 默认不可变 |
let x = 5 (可变) | let mut x = 5 | Rust 需要显式声明可变 |
const | const / static | Rust 的 const 是编译期常量 |
string | String / &str | Rust 区分拥有的字符串和借用的字符串切片 |
number | i32 / f64 / u8 等 | Rust 有精确的数字类型 |
boolean | bool | 一样 |
null / undefined | 没有!用 Option<T> | Rust 没有空值 |
Array<T> | Vec<T> | 动态数组 |
[1, 2, 3] (固定) | [1, 2, 3] | 固定长度数组 |
Map<K, V> | HashMap<K, V> | 哈希映射 |
Set<T> | HashSet<T> | 哈希集合 |
interface | trait | 定义行为契约 |
type A = B | C | enum { B, C } | 联合类型 → 枚举 |
class | struct + impl | Rust 没有类,用结构体 + 方法实现 |
继承 (extends) | Trait 组合 | Rust 不支持继承,用组合 |
(x: number) => x * 2 | |x: i32| x * 2 | 闭包/匿名函数 |
async/await | async/await | 语法几乎一样,但底层机制不同 |
Promise<T> | Future<Output = T> | 异步值 |
try {} catch {} | Result<T, E> + ? | 错误处理 |
throw new Error() | Err(e) 或 panic!() | 抛出错误 |
typeof | 无对应(编译期已知) | Rust 是静态类型,不需要运行时检查 |
import {} from | use crate:: | 模块导入 |
export | pub | 公开可见性 |
泛型 <T> | 泛型 <T> | 语法几乎一样 |
T extends U | T: U (trait bound) | 泛型约束 |
0.4.3 项目结构映射
TypeScript 项目 Rust 项目
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
my-app/ my-app/
├── package.json ├── Cargo.toml
├── package-lock.json ├── Cargo.lock
├── tsconfig.json │ (配置在 Cargo.toml 中)
├── node_modules/ ├── target/
│ └── (依赖) │ ├── debug/
│ │ └── release/
├── src/ ├── src/
│ ├── index.ts │ ├── main.rs (二进制入口)
│ │ │ ├── lib.rs (库入口)
│ ├── utils/ │ ├── utils/
│ │ ├── index.ts │ │ ├── mod.rs (模块声明)
│ │ └── helpers.ts │ │ └── helpers.rs
│ └── types/ │ └── models/
│ └── user.ts │ └── user.rs
├── tests/ ├── tests/ (集成测试)
│ └── user.test.ts │ └── user_test.rs
├── dist/ │ (target/ 就是输出目录)
├── .eslintrc │ (clippy 内置)
├── .prettierrc │ (rustfmt 内置)
└── README.md └── README.md
💡 关键差异:
- Rust 不需要单独的 linter 和 formatter 配置,
clippy和rustfmt是官方标配 - Rust 没有
dist/目录,编译产物在target/中 - Rust 的单元测试通常写在源文件内部(这个设计很巧妙!)
0.4.4 常用命令映射
# ====== npm / pnpm ====== # ====== cargo ======
npm init cargo init / cargo new
npm install cargo build
npm install express cargo add axum
npm run dev cargo run
npm run build cargo build --release
npm test cargo test
npx prettier --write . cargo fmt
npx eslint . cargo clippy
npm publish cargo publish
npm run lint cargo clippy -- -D warnings
npm outdated cargo outdated (需安装)
npm audit cargo audit (需安装)
0.4.5 开发工作流映射
Web 开发工作流 Rust 开发工作流
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 写代码 1. 写代码
(VS Code + TS) (VS Code + rust-analyzer)
2. 热更新预览 2. cargo run / cargo watch
(HMR / 浏览器刷新) (每次修改需重新编译)
3. TypeScript 类型检查 3. 编译器检查
(tsc --noEmit) (cargo check)
"红色波浪线" "红色波浪线" + 详细错误信息
4. Lint 检查 4. Clippy 检查
(ESLint) (cargo clippy)
5. 格式化 5. 格式化
(Prettier) (cargo fmt)
6. 测试 6. 测试
(Jest / Vitest) (cargo test) —— 内置!
7. 构建 7. 构建
(tsc + bundler) (cargo build --release)
8. 部署 8. 部署
(Docker + Node.js) (复制单个二进制文件即可!)
💡 一个令人惊喜的差异:Rust 的部署极其简单。编译后你得到一个单个可执行文件,没有运行时依赖,直接拷贝到服务器就能运行。不需要 Node.js,不需要 Docker(虽然你仍然可以用 Docker),不需要 npm install。
0.5 Rust 的核心设计哲学
0.5.1 零成本抽象 (Zero-Cost Abstractions)
这是 Rust 从 C++ 继承的核心理念,但 Rust 做得更好。
什么是零成本抽象?
“你不用为你不使用的东西付出代价; 对于你使用的东西,你也不可能手写出比它更好的代码。” —— Bjarne Stroustrup (C++ 之父)
用 Web 开发的语言来解释:
// ====== TypeScript ======
// 使用高级抽象 .map().filter() 会创建中间数组
const result = users
.filter(u => u.active) // 创建新数组 1
.map(u => u.name) // 创建新数组 2
.filter(n => n.startsWith('A')) // 创建新数组 3
.map(n => n.toUpperCase()); // 创建新数组 4
// 总共分配了 4 个临时数组,GC 稍后需要回收它们
// 手动优化版本(只遍历一次,一个数组)
const result2: string[] = [];
for (const u of users) {
if (u.active && u.name.startsWith('A')) {
result2.push(u.name.toUpperCase());
}
}
// 更快,但代码不如链式调用优雅
// ====== Rust ======
// 迭代器是惰性的(lazy),不会创建中间集合!
let result: Vec<String> = users.iter()
.filter(|u| u.active) // 不创建中间集合
.map(|u| &u.name) // 不创建中间集合
.filter(|n| n.starts_with('A')) // 不创建中间集合
.map(|n| n.to_uppercase()) // 不创建中间集合
.collect(); // 只在最后一步创建一个 Vec
// 编译器会把这段代码优化成等价于手写 for 循环的机器码
// 高级抽象 + 手写性能 = 零成本抽象 ✨
💡 TS 类比:想象如果 JavaScript 的 .map().filter() 链式调用跟手写 for 循环一样快 —— 这就是 Rust 的零成本抽象。你可以写出优雅的函数式代码,性能却和底层命令式代码一样。
0.5.2 所有权系统 (Ownership)
这是 Rust 最核心、最独特的概念。如果你只记住一件事,就记住这个。
用搬家来类比:
生活中的类比
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
场景:你有一本书
JavaScript 的做法(引用 + GC):
你把书放在共享书架上
任何人都可以来读
没人读了?管理员(GC)会来清理
问题:管理员什么时候来?没准儿。
有时候管理员太忙了,书架就满了(内存压力)
C++ 的做法(手动管理):
你把书给别人
约定好谁来还、什么时候还
问题:经常忘记还(内存泄漏)
或者两个人都以为自己该还(双重释放)
或者书被还了但有人还在看(悬垂指针)
Rust 的做法(所有权):
每本书有且只有一个主人
你可以把书借给别人看(借用 &),但主人不变
你也可以把书的所有权转移给别人(移动 move)
当主人离开房间时,书自动销毁
规则很清晰,不可能出错
用代码来看:
fn main() {
// ===== 所有权规则 =====
// 规则 1:每个值有且只有一个所有者
let s1 = String::from("hello"); // s1 是 "hello" 的所有者
// 规则 2:当所有者离开作用域,值被销毁
{
let s2 = String::from("world"); // s2 拥有 "world"
} // s2 离开作用域,"world" 被自动释放 —— 不需要 GC!
// 规则 3:所有权可以转移(move)
let s3 = s1; // s1 的所有权转移给 s3
// println!("{}", s1); // ❌ 编译错误!s1 已经失效了
println!("{}", s3); // ✅ s3 现在拥有 "hello"
}
💡 TS 类比: 想象如果 TypeScript 有这样一条规则:一个变量赋值给另一个变量后,原变量就不能再用了。
// 假设 TypeScript 有所有权系统
let s1 = "hello";
let s3 = s1; // s1 的所有权转移给 s3
console.log(s1); // ❌ 编译错误:s1 已被移动
// 这在 TS 中听起来很荒谬,但这正是 Rust 的规则
// 这条规则阻止了:悬垂引用、双重释放、数据竞争
0.5.3 借用系统 (Borrowing)
如果每次传递数据都要转移所有权,那也太不方便了。所以 Rust 有借用:
fn main() {
let s = String::from("hello");
// 不可变借用(&):可以读,不能改
// 可以同时有多个不可变借用
let len = calculate_length(&s); // 借用 s,但不拿走所有权
println!("'{}' 的长度是 {}", s, len); // s 依然可用!
// 可变借用(&mut):可以读也可以改
// 但同一时间只能有一个可变借用
let mut s2 = String::from("hello");
change(&mut s2);
println!("{}", s2); // 输出 "hello, world"
}
fn calculate_length(s: &String) -> usize { // 接收引用,不拿走所有权
s.len()
}
fn change(s: &mut String) { // 接收可变引用
s.push_str(", world");
}
借用的核心规则(很重要!):
Rust 借用规则
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
规则 1:在任一时刻,你可以拥有:
- 任意数量的不可变引用(&T),或者
- 恰好一个可变引用(&mut T)
但不能同时拥有两者
规则 2:引用必须总是有效的
(不能引用已经被释放的数据)
💡 TS 类比:
// 这就像一个读写锁:
// 多个人可以同时阅读一本书(多个 &T)
// 或者一个人可以在书上做笔记(一个 &mut T)
// 但不能同时有人阅读和有人做笔记
// 否则读者看到的可能是写到一半的内容
0.5.4 无垃圾回收 (No GC)
JavaScript/TypeScript 运行时有垃圾回收器(Garbage Collector),它会:
JavaScript 的 GC 工作流程
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 你创建对象 → 分配在堆上
2. 你使用对象 → 正常运行
3. 你不再使用对象 → 对象变成"垃圾"
4. GC 启动(时机不确定)
├── 标记阶段:扫描所有对象,标记哪些还在使用
├── 清除阶段:释放未标记的对象
└── 压缩阶段:整理内存碎片
5. 在 GC 运行期间,你的程序可能会暂停(Stop the World)
问题:
├── 内存使用通常是实际需要的 2-3 倍
├── GC 暂停导致延迟抖动(P99 延迟不可控)
├── GC 何时运行不可预测
└── 难以用于实时系统(游戏、音频、交易系统)
Rust 的内存管理
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 你创建值 → 所有权规则确定由谁负责
2. 你使用值 → 借用规则确保安全
3. 所有者离开作用域 → 值立即释放(确定性析构)
没有 GC 线程
没有 Stop the World
没有内存膨胀
延迟完全可预测
这就是 Discord 从 Go 切换到 Rust 后
P99 延迟从几百毫秒降到个位数毫秒的原因
0.5.5 编译器是你的朋友
Rust 编译器(rustc)以严格著称,但它给出的错误信息堪称艺术品。
// 假设你写了这段代码:
fn main() {
let s = String::from("hello");
let s2 = s;
println!("{}", s);
}
// 编译器会告诉你:
// error[E0382]: borrow of moved value: `s`
// --> src/main.rs:4:20
// |
// 2 | let s = String::from("hello");
// | - move occurs because `s` has type `String`,
// | which does not implement the `Copy` trait
// 3 | let s2 = s;
// | - value moved here
// 4 | println!("{}", s);
// | ^ value borrowed here after move
// |
// = note: consider cloning the value if the performance
// cost is acceptable
// help: consider cloning the value
// |
// 3 | let s2 = s.clone();
// | ++++++++
注意看:编译器不仅告诉你哪里出错了,还告诉你为什么出错,甚至给出了修复建议!
💡 TS 类比:想象如果 TypeScript 的类型错误不仅显示红色波浪线,还会告诉你”试试这样改就好了”,并且给出可以直接复制粘贴的修复代码。Rust 编译器就是这样的体验。
0.6 Rust 生态全景
Rust 的生态虽然不如 JavaScript/Python 那么庞大,但在每个领域都有高质量的库。
0.6.1 Web 后端
Web 框架 对标 JS 框架
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Axum -- Tokio 团队出品,模块化设计 ≈ Express/Koa
Actix-Web -- 性能王者,Actor 模型 ≈ Fastify
Rocket -- 优雅的 API,类似 Flask ≈ Hono
Warp -- 基于 Filter 组合 ≈ 函数式 Express
Poem -- 国人开发,简洁优雅 ≈ Hono
Loco -- 全栈框架,类似 Rails ≈ Next.js (后端)
ORM / 数据库
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SQLx -- 编译期校验 SQL 语句 ≈ Prisma (类型安全)
Diesel -- 全功能 ORM ≈ TypeORM
SeaORM -- 异步 ORM,灵感来自 ActiveRecord ≈ Sequelize
SurrealDB -- Rust 写的新型数据库 ≈ —
0.6.2 CLI 工具
CLI 框架
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
clap -- 命令行参数解析(最流行) ≈ yargs / commander
dialoguer -- 交互式 CLI 提示 ≈ inquirer
indicatif -- 进度条 ≈ ora
console -- 终端颜色和样式 ≈ chalk
ratatui -- 终端 UI 框架(TUI) ≈ blessed / ink
知名的 Rust CLI 工具
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ripgrep (rg) -- 替代 grep,快 10 倍
fd -- 替代 find,更友好
bat -- 替代 cat,带语法高亮
exa/eza -- 替代 ls,带颜色和图标
delta -- 替代 diff,美化 Git diff
zoxide (z) -- 替代 cd,智能跳转
starship -- 跨 shell 的美化提示符
tokei -- 代码行数统计
hyperfine -- 命令行基准测试工具
just -- 替代 make,更现代
0.6.3 WebAssembly (WASM)
这是 Rust 与前端开发者最直接的交集。
Rust + WASM 生态
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
wasm-pack -- 打包 Rust → npm 包
wasm-bindgen -- Rust ↔ JavaScript 互操作
web-sys -- Web API 的 Rust 绑定
js-sys -- JavaScript 标准库的 Rust 绑定
Yew -- 类 React 的 Rust 前端框架
Leptos -- 响应式 Rust 前端框架
Dioxus -- 跨平台 UI 框架(Web/桌面/移动)
Trunk -- Rust WASM 应用的构建工具
实际应用
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Figma -- 多人协作引擎用 Rust WASM
Photon -- 图像处理库(浏览器中运行)
Squoosh -- Google 的图片压缩工具(WASM 核心)
源映射解析 -- source-map 库用 Rust WASM 重写,快 5 倍
💡 对 TS/JS 开发者的意义:你可以用 Rust 编写性能关键的代码,编译成 WASM,然后在浏览器或 Node.js 中像普通 npm 包一样调用。你的前端技能 + Rust = 超能力。
0.6.4 嵌入式与系统编程
嵌入式生态
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
embedded-hal -- 硬件抽象层标准
probe-rs -- 调试和烧录工具
Embassy -- 异步嵌入式框架(类似 Tokio,但用于单片机)
RTIC -- 实时中断驱动框架
操作系统
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Linux 内核 -- Rust 作为第二语言被正式引入
Redox OS -- 纯 Rust 编写的类 Unix 操作系统
Theseus OS -- 研究型操作系统
0.6.5 区块链与密码学
区块链生态
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Solana -- 高性能区块链,智能合约用 Rust
Polkadot -- 跨链协议,Substrate 框架用 Rust
Near Protocol -- 智能合约用 Rust
Aptos / Sui -- 新一代区块链,Move 语言(Rust 系生态)
Zcash -- 隐私加密货币
0.6.6 AI 与机器学习
AI/ML 生态(快速增长中)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Candle -- Hugging Face 的 Rust ML 框架
Burn -- 深度学习框架
tch-rs -- PyTorch 的 Rust 绑定
tokenizers -- Hugging Face 分词器(Rust 核心)
llm -- 本地运行 LLM
0.6.7 生态总结
JavaScript 生态 vs Rust 生态
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
npm 包数量: ~2,500,000+
crates.io 包数量:~150,000+
但是:
├── Rust 的包平均质量更高(编译器强制的质量门槛)
├── Rust 的包文档通常更完善(rustdoc 文化)
├── Rust 没有 left-pad 事件(因为标准库足够丰富)
└── Rust 社区对"小而精"的包更有共识
0.7 本教程将构建的项目
我们不会只写玩具代码。在学习过程中,你会构建这些实际可用的项目:
项目 1:minigrep —— CLI 搜索工具(Part 1)
minigrep - 一个简化版的 grep
├── 📝 命令行参数解析
├── 📂 文件读取
├── 🔍 文本搜索(区分大小写 / 不区分)
├── ✅ 完整的单元测试
└── 📚 学到的概念:
├── 所有权与借用
├── 错误处理(Result)
├── 模块组织
├── 迭代器与闭包
└── 测试驱动开发
项目 2:json-parser —— JSON 解析器(Part 2)
json-parser - 从零实现 JSON 解析器
├── 📝 词法分析(Lexer / Tokenizer)
├── 🌳 语法分析(Parser → AST)
├── 🔄 序列化 / 反序列化
├── ⚡ 性能对比(vs serde_json)
└── 📚 学到的概念:
├── 枚举与模式匹配
├── 递归数据结构
├── 泛型与 Trait
├── 生命周期
└── 性能优化
项目 3:axum-api —— REST API 服务(Part 3)
axum-api - 完整的 REST API 后端
├── 🌐 RESTful 路由设计
├── 🔐 JWT 认证与授权
├── 🗄️ PostgreSQL 数据库(SQLx)
├── 📋 CRUD 操作
├── 🧪 集成测试
├── 📖 OpenAPI 文档生成
├── 🐳 Docker 部署
└── 📚 学到的概念:
├── 异步编程(async/await)
├── 中间件模式
├── 数据库操作
├── 错误处理最佳实践
└── 项目架构
项目 4:wasm-image-editor —— WASM 图片编辑器(Part 3)
wasm-image-editor - 浏览器端图片处理
├── 🖼️ 图片加载与显示
├── 🎨 滤镜效果(灰度、模糊、锐化)
├── 📐 裁剪与缩放
├── ⚡ 与纯 JS 版本的性能对比
├── 📦 打包为 npm 包
└── 📚 学到的概念:
├── Rust → WASM 编译
├── JS ↔ Rust 互操作
├── 内存布局与 ArrayBuffer
└── Web Worker 集成
0.8 学习路线图
0.8.1 分阶段学习计划
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌱 阶段一:入门基础(第 00-06 章,约 3-4 周)
目标:能写出基础 Rust 程序,理解所有权
第 00 章 全景概览(就是本章!) ← 你在这里
第 01 章 环境搭建
第 02 章 变量、类型与函数
第 03 章 所有权与借用(最重要的一章!)
第 04 章 结构体与枚举
第 05 章 模式匹配与错误处理
第 06 章 模块系统与 Cargo
🎯 里程碑:完成 minigrep 项目
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌿 阶段二:核心进阶(第 07-12 章,约 3-4 周)
目标:掌握 Rust 的高级类型系统特性
第 07 章 泛型与 Trait
第 08 章 生命周期
第 09 章 集合与迭代器
第 10 章 闭包与函数式编程
第 11 章 智能指针
第 12 章 并发编程
🎯 里程碑:完成 json-parser 项目
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🌳 阶段三:实战应用(第 13-18 章,约 3-4 周)
目标:能用 Rust 构建完整的应用
第 13 章 CLI 工具开发
第 14 章 文件 I/O 与序列化
第 15 章 网络编程
第 16 章 Web 框架实战
第 17 章 数据库操作
第 18 章 WebAssembly
🎯 里程碑:完成 axum-api 和 wasm-image-editor 项目
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🏔️ 阶段四:高级主题(第 19-24 章,约 3-4 周)
目标:深入理解 Rust 底层机制,参与开源生态
第 19 章 宏编程
第 20 章 unsafe 与 FFI
第 21 章 异步运行时深入
第 22 章 性能优化
第 23 章 设计模式
第 24 章 生态与开源贡献
🎯 里程碑:向一个 Rust 开源项目提交 PR
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
0.8.2 每周学习建议
推荐的一周学习节奏(每周 10-15 小时)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
周一/周二 📖 阅读教程章节,跟着敲代码
周三/周四 💻 做章节练习题
周五 🔧 在自己的项目中尝试用 Rust
周末 🧪 自由探索:读源码、看文档、刷 Exercism
0.8.3 推荐的补充学习资源
官方资源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📕 The Rust Programming Language (The Book)
https://doc.rust-lang.org/book/
(官方教材,必读)
📗 Rust by Example
https://doc.rust-lang.org/rust-by-example/
(通过示例学习)
📘 Rustlings
https://github.com/rust-lang/rustlings
(交互式小练习)
📙 Rust Playground
https://play.rust-lang.org/
(在线运行 Rust 代码)
中文资源
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📕 Rust 语言圣经 (course.rs)
https://course.rs/
(中文社区最好的 Rust 教程之一)
📗 Rust 程序设计语言(中文翻译)
https://kaisery.github.io/trpl-zh-cn/
(官方 Book 的高质量中文翻译)
练习平台
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🏋️ Exercism Rust Track
https://exercism.org/tracks/rust
(有导师反馈的练习)
🎮 Advent of Code
https://adventofcode.com/
(每年 12 月的编程挑战,用 Rust 来做!)
0.9 常见问题 FAQ
Q1:Rust 真的很难学吗?
实话实说:是的,Rust 的学习曲线比大多数语言都陡。 但难的不是语法(Rust 的语法对 TS 开发者来说其实很亲切),难的是所有权和生命周期这些新概念。
好消息是:一旦你跨过了所有权这道坎(通常需要 2-4 周),后面就会越来越顺。而且你学到的这些概念会让你成为更好的程序员 —— 即使你之后回去写 TypeScript。
学习曲线对比
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Python: ____/‾‾‾‾‾‾‾‾‾‾‾‾‾ (快速上手,缓慢提升)
Go: ___/‾‾‾‾‾‾‾‾‾‾‾‾‾‾ (中速上手,缓慢提升)
Rust: _________/‾‾‾‾‾‾‾‾ (痛苦期 → 顿悟 → 顺畅)
C++: ___/‾‾‾‾‾‾‾‾‾ ∿ ∿ (上手容易,但坑越来越多)
Q2:学 Rust 会影响我写 TypeScript 吗?
会,而且是好的影响。 学了 Rust 之后,你会:
- 更注意内存和性能
- 更好地理解
Promise和异步的底层原理 - 写出更好的 TypeScript 类型定义
- 理解为什么某些 npm 包用 Rust 重写后快了 100 倍
- 能够为前端工具链贡献代码
Q3:我应该用 Rust 替代 TypeScript 吗?
不应该。 它们是互补的:
用 TypeScript 的场景 用 Rust 的场景
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Web 前端 UI ✅ 性能关键的计算模块 (WASM)
✅ 快速原型开发 ✅ CLI 工具
✅ REST API(大多数场景) ✅ 高性能后端服务
✅ 全栈应用(Next.js 等) ✅ 系统级工具
✅ 移动端(React Native) ✅ 嵌入式 / IoT
✅ 脚本和自动化 ✅ 基础设施组件
Q4:Rust 适合做 Web 后端吗?
适合,但要看场景。
- 如果你需要极致性能(高并发、低延迟)→ Rust 是绝佳选择
- 如果你在做快速迭代的创业项目 → TypeScript 或 Go 可能更合适
- 如果你的团队都熟悉 Rust → 当然可以
Rust 的 Web 框架(Axum、Actix-Web)在性能基准测试中常年霸榜,但开发速度确实比 Express/Fastify 慢一些。
Q5:我需要理解操作系统和计算机底层知识吗?
不需要。 本教程假设你只有 Web 开发背景。我们会在需要的时候解释底层概念(比如栈和堆),但不会要求你预先掌握这些知识。
0.10 让我们开始吧!
恭喜你读完了全景概览!现在你应该对 Rust 有了一个整体的认知:
✅ 你知道了为什么 TS/JS 开发者应该学 Rust
✅ 你了解了 Rust 的历史和设计哲学
✅ 你看到了 Rust 与其他语言的详细对比
✅ 你有了一张 Web 概念 → Rust 概念的映射表
✅ 你初步理解了所有权、借用、无 GC 的概念
✅ 你了解了 Rust 的生态全景
✅ 你知道了我们将构建什么项目
✅ 你有了清晰的学习路线图
在下一章中,我们将搭建 Rust 开发环境(Rustup + Cargo + VS Code),并写出你的第一个 Rust 程序。
fn main() {
println!("你好,Rust 世界!🦀");
println!("从 TypeScript 到 Rust 的旅程,现在开始。");
}