Chapter 01

Rust 简介与开发环境

了解 Rust 的诞生故事、核心设计哲学,并搭建完整的本地开发环境

Rust 的诞生与历史

从一次电梯故障说起

2006 年,Mozilla 工程师 Graydon Hoare 住在公寓里,某天电梯坏了。他发现电梯控制软件崩溃了——而这类嵌入式系统通常用 C 或 C++ 编写。崩溃的根源往往是内存安全问题:一个悬垂指针、一次越界访问,就可能让整个程序崩溃。他思考:为什么 2006 年了,我们还在被这类问题困扰?

这个念头促使他开始了一个业余项目——设计一门新的系统编程语言,它要能像 C 一样高效,像现代语言一样安全。这就是 Rust 的起点。

关键时间线

2006 年
Graydon Hoare 开始个人项目,最初的 Rust 编译器用 OCaml 编写。
2009 年
Mozilla 开始赞助 Rust 项目,组建专职团队,转向用 Rust 自举(bootstrapping)。
2012 年
发布第一个对外公开版本 Rust 0.1,语法变化剧烈,借鉴 ML、Haskell、C++ 等多种语言。
2015 年
发布 Rust 1.0,承诺向后兼容。所有权系统基本定型,正式进入生产使用阶段。
2018 年
Rust 2018 Edition,改进生命周期省略规则,引入 async/await 语法(完整支持在 1.39)。
2021 年
Rust 2021 Edition,改进闭包捕获规则、Trait Resolver v2,成立 Rust Foundation。
2024 年
Rust 2024 Edition,进入 Linux 内核官方支持,Android 平台大规模采用。

谁在用 Rust?

Rust 已经从小众语言成长为工业级选择:

Rust 的核心设计哲学

三大承诺

Rust 的设计目标可以用三个词概括:安全(Safe)快速(Fast)并发(Concurrent)。更准确的说法是:

Rust 的核心承诺

内存安全,不需要 GC:通过所有权系统在编译期保证,不产生运行时开销。
零成本抽象:你使用的高级抽象(泛型、迭代器等)编译后的代码和手写底层代码一样高效。
无畏并发:类型系统防止数据竞争,让你在编译期发现并发错误,而不是在生产环境崩溃。

与其他语言的对比

特性 C/C++ Go Java/Python Rust
内存管理 手动 malloc/free 垃圾回收 GC 垃圾回收 GC 所有权系统(编译期)
内存安全 不保证 基本保证 保证 编译期完全保证
运行时开销 极低 GC 暂停 GC + JVM 开销 极低(无 GC)
数据竞争 运行时出现 基本防止 运行时出现 编译期防止
抽象能力 中等 较强 强(零成本)
学习曲线 中等 平缓 平缓 陡峭

为什么 Rust 学习曲线陡峭?

Rust 的难点不在于语法,而在于所有权系统——这是一套你在其他语言中从未接触过的概念体系。当你写 let y = x; 时,在大多数语言里是简单的赋值或引用复制,但在 Rust 中可能意味着所有权的转移,之后再使用 x 会导致编译错误。

这种"与编译器搏斗"的初期体验是真实的,但一旦你理解了所有权系统,你会发现编译器是你最好的队友——它在代码运行之前就替你找出了所有潜在的内存问题。

安装开发环境

rustup:官方工具链管理器

rustup 是 Rust 官方提供的工具链版本管理器,类似于 Node.js 生态中的 nvm。它负责安装和管理不同版本的 Rust 编译器、标准库和工具。

# macOS / Linux:一行安装
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Windows:下载并运行 rustup-init.exe
# 访问 https://rustup.rs 获取安装程序

# 安装完成后,重新加载 shell 配置(或重启终端)
source $HOME/.cargo/env

# 验证安装
rustc --version    # rustc 1.77.0 (aedd173a2 2024-03-17)
cargo --version    # cargo 1.77.0 (ef5e5bba6 2024-03-15)
rustup --version   # rustup 1.27.0 (bbb9276d2 2024-03-08)

管理 Rust 版本

# 更新到最新稳定版
rustup update

# 安装 nightly 工具链(用于实验性特性)
rustup install nightly

# 为特定项目设置工具链
rustup override set nightly

# 查看已安装的工具链
rustup toolchain list

# 添加编译目标(例如 WebAssembly)
rustup target add wasm32-unknown-unknown
推荐使用稳定版(stable)

日常开发请始终使用稳定版工具链。nightly 版包含未稳定的特性,API 可能随时变化,只在需要特定实验性功能时才切换。

Cargo:Rust 的构建工具与包管理器

Cargo 是什么?

Cargo 是 Rust 的官方构建系统和包管理器,它一体化地处理了:依赖下载与版本管理、代码编译、测试运行、文档生成、代码发布。在其他语言生态中,这些职责往往分散在多个工具中(如 npm + webpack + jest),而 Cargo 将它们统一起来,大大降低了工程配置复杂度。

创建第一个项目

# 创建新的二进制(可执行)项目
cargo new hello_rust
cd hello_rust

# 创建新的库项目
cargo new my_lib --lib

# 项目目录结构
hello_rust/
├── Cargo.toml      # 项目清单:名称、版本、依赖
├── Cargo.lock      # 依赖锁定文件(类似 package-lock.json)
└── src/
    └── main.rs     # 程序入口

Cargo.toml 解析

[package]
name = "hello_rust"
version = "0.1.0"
edition = "2024"         # Rust Edition,影响某些语法行为
authors = ["Your Name <you@example.com>"]
description = "My first Rust project"

[dependencies]
# 格式:crate_name = "版本号"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

[dev-dependencies]
# 仅用于测试和基准测试的依赖
assert_cmd = "2.0"

[[bin]]
# 如果项目有多个可执行文件,在这里声明
name = "hello"
path = "src/main.rs"

常用 Cargo 命令

cargo build           # 编译(debug 模式)
cargo build --release # 编译(release 模式,开启优化)
cargo run             # 编译并运行
cargo run -- --args   # 传递命令行参数
cargo test            # 运行所有测试
cargo doc --open      # 生成并打开文档
cargo check           # 只检查语法错误,不生成可执行文件(最快)
cargo clippy          # 运行 lint 检查
cargo fmt             # 格式化代码
cargo add serde       # 添加依赖到 Cargo.toml
cargo update          # 更新依赖版本
debug vs release 模式的区别

cargo build 默认使用 debug 模式:编译快,但不开启优化,二进制文件包含调试符号,体积大、运行慢。
cargo build --release 使用 release 模式:编译慢(开启全部优化),但运行速度可比 debug 快 10-100 倍,适合生产部署。

代码质量工具

rustfmt:代码格式化

Rust 社区有一套统一的代码风格规范,rustfmt 负责自动执行格式化,消除团队内的代码风格争论。

# 格式化当前项目所有文件
cargo fmt

# 只检查格式问题,不修改文件(CI 中使用)
cargo fmt -- --check

# 配置文件(放在项目根目录)
# rustfmt.toml
max_width = 100
tab_spaces = 4
edition = "2024"

clippy:Rust 代码检查器

Clippy 是 Rust 官方提供的 lint 工具,包含超过 700 条检查规则,能发现代码中的常见错误模式、性能问题、以及不符合 Rust 惯用法的代码。

# 运行 clippy
cargo clippy

# 将警告视为错误(CI 中推荐使用)
cargo clippy -- -D warnings

# clippy 示例:它会检查这类代码
// 不好的写法:clippy 会建议改进
let v: Vec<i32> = Vec::new();  // clippy 建议用 vec![]
if v.len() == 0 { }             // clippy 建议用 v.is_empty()
let x = &*v;                    // clippy 建议去掉多余的 &*

// 允许特定 lint(在代码中标注)
#[allow(clippy::needless_pass_by_value)]
fn process(data: String) { }

IDE 与编辑器支持

rust-analyzer
官方语言服务器(LSP),提供代码补全、错误提示、跳转定义、重构等功能。支持 VS Code、Neovim、Emacs、JetBrains IDE 等。
VS Code
安装「rust-analyzer」扩展,是目前最流行的 Rust 开发环境,功能完整且免费。
RustRover
JetBrains 专门为 Rust 开发的 IDE,提供深度集成的调试、性能分析工具。非商业用途免费。
Zed
用 Rust 编写的高性能编辑器,内置 rust-analyzer,启动速度极快。

Hello, World! 详解

第一个 Rust 程序

// src/main.rs
fn main() {
    println!("Hello, World!");
}

这几行代码虽然简单,但包含了 Rust 的几个重要特征:

格式化输出

fn main() {
    let name = "Rust";
    let year = 2015;

    // {} 是默认格式化占位符
    println!("Hello, {}! 诞生于 {} 年。", name, year);

    // {:?} 用于调试输出(需要实现 Debug trait)
    let arr = [1, 2, 3];
    println!("数组:{:?}", arr);

    // {:#?} 美化调试输出
    println!("美化输出:{:#?}", arr);

    // 命名参数
    println!("{lang} 是系统编程语言", lang = "Rust");

    // 格式化数字
    println!("{:.2}", 3.14159);   // 保留两位小数: 3.14
    println!("{:08b}", 42);       // 二进制,宽度8位: 00101010
    println!("{:x}", 255);        // 十六进制: ff
}
println! 与 print! 的区别

println! 输出后自动添加换行符,print! 不添加。还有 eprintln!eprint! 用于输出到标准错误流(stderr)。