第1章 Rust入门与生态:从历史到第一个可运行的程序
Rust 是一门由 Mozilla Research 主导开发、于 2015 年发布 1.0 稳定版的系统级编程语言。它的诞生源于一个长期困扰 C/C++ 社区的难题:如何在保证内存安全的前提下,不牺牲性能与控制力。Rust 的设计目标可以概括为“安全、并发、务实”——它通过所有权(Ownership)、借用(Borrowing)和生命周期(Lifetime)三大核心机制,在编译期消除数据竞争、空指针、悬垂指针等内存错误,同时不引入垃圾回收(GC)带来的运行时开销。本章作为 45 天精通 Rust 的第一课,将带你完成从理解 Rust 的定位、安装工具链,到使用 Cargo 创建并运行第一个项目的完整闭环。
1.1 Rust 的历史与设计目标
Rust 最早由 Graydon Hoare 于 2006 年在 Mozilla 开始作为个人项目,2009 年 Mozilla 正式赞助,2015 年 5 月 15 日发布 1.0 稳定版。它的诞生背景非常具体:Firefox 浏览器中的 CSS 引擎 Servo 需要一种既能提供高性能、又能避免 C++ 中常见内存错误(如缓冲区溢出、释放后使用)的语言。Rust 的设计目标并非“取代 C++”,而是为系统编程提供一种更安全、更现代的选择。
Rust 的核心设计目标可以归纳为以下四点:
- 内存安全:通过所有权和借用检查器,在编译期杜绝空指针、悬垂指针、双重释放等问题,不需要垃圾回收器。
- 无畏并发:编译器在编译期检查数据竞争,使得多线程代码可以安全地共享数据,而不需要繁琐的锁。
- 零成本抽象:高级语言特性(如泛型、迭代器、闭包)在编译后生成的机器码与手写底层代码性能相当。
- 实用主义:提供包管理器 Cargo、内置测试框架、文档生成工具,让工程化体验接近现代高级语言。
为什么选择 Rust? 如果你需要编写操作系统内核、嵌入式固件、游戏引擎、数据库引擎、WebAssembly 模块或高性能网络服务,Rust 能让你在享受现代语言表达能力的同时,获得与 C/C++ 相当的性能。它的学习曲线较陡,但一旦掌握所有权模型,代码的健壮性会显著提升。
1.2 安装 Rust 工具链
Rust 官方推荐的安装方式是使用 rustup,它是一个版本管理器和工具链安装器。rustup 允许你安装多个 Rust 版本(stable、beta、nightly)并在它们之间切换,同时管理交叉编译目标。
安装步骤(Linux/macOS):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
安装完成后,需要将 Cargo 的 bin 目录添加到 PATH 环境变量。rustup 会自动在 ~/.cargo/env 中写入配置,你只需执行:
source ~/.cargo/env
Windows 用户:请前往 rustup.rs 下载 rustup-init.exe,运行后按提示操作。Windows 上 Rust 需要 MSVC 构建工具(Visual Studio Build Tools)或 GNU 工具链,建议选择 MSVC 版本。
安装完成后,验证工具链是否正常:
rustc --version
cargo --version
rustup --version
你应该看到类似如下的输出:
rustc 1.78.0 (9b00956e5 2024-04-29)
cargo 1.78.0 (54d8815d0 2024-04-29)
rustup 1.27.1 (54dd3d00f 2024-04-24)
| 工具 | 作用 | 常用命令 |
|---|---|---|
| rustup | 管理 Rust 工具链版本 | rustup update / rustup default stable |
| rustc | Rust 编译器 | rustc main.rs |
| cargo | 包管理器与构建系统 | cargo new / cargo build / cargo run |
| rustfmt | 代码格式化工具 | cargo fmt |
| clippy | 静态代码检查工具 | cargo clippy |
经验提醒:如果你在安装过程中遇到网络问题,可以设置镜像源。中国用户可以使用字节跳动的镜像:export RUSTUP_DIST_SERVER=https://rsproxy.cn 和 export RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup。
1.3 使用 Cargo 创建第一个项目
Cargo 是 Rust 的官方构建系统和包管理器,类似于 Python 的 pip + setuptools、Node.js 的 npm。它负责依赖管理、编译、测试、文档生成和发布。Cargo 的核心理念是“约定优于配置”——项目结构有标准模板,无需手动编写构建脚本。
创建新项目的标准流程:
- 打开终端,进入你希望存放项目的目录。
- 执行
cargo new hello_world,Cargo 会自动生成一个名为hello_world的目录。 - 进入项目目录:
cd hello_world。 - 查看生成的文件结构。
- 编辑
src/main.rs写入代码。 - 执行
cargo run编译并运行。
执行 cargo new hello_world 后,Cargo 会生成以下结构:
hello_world/
├── Cargo.toml # 项目清单文件(类似 package.json)
├── .gitignore # Git 忽略规则
└── src/
└── main.rs # 主程序入口
Cargo.toml 是项目的核心配置文件,默认内容如下:
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
[dependencies]
其中 edition 字段指定了 Rust 的版本版本(2015、2018、2021、2024),它影响语言特性的可用性。目前推荐使用 2021 或 2024 edition。
src/main.rs 的默认内容为:
fn main() {
println!("Hello, world!");
}
这是 Rust 程序的最小完整结构:fn main() 是程序的入口点,所有可执行程序都必须包含一个 main 函数。println! 是一个宏(注意末尾的感叹号),用于向标准输出打印一行文本并换行。
1.4 理解 main 函数与 println! 宏
main 函数是 Rust 可执行程序的唯一入口。它的签名固定为 fn main(),不接受参数,不返回任何值(实际上可以返回 Result 类型,但默认返回单元类型 ())。当程序启动时,操作系统调用 main 函数;当 main 函数执行完毕,程序退出。
println! 宏是 Rust 中最常用的输出宏。它支持格式化字符串,语法与 Python 的 f-string 和 C 的 printf 类似,但更安全——编译器会在编译期检查格式字符串与参数是否匹配。
基本用法示例:
fn main() {
let name = "Alice";
let age = 30;
// 最简单的用法:打印字符串字面量
println!("Hello, world!");
// 使用占位符 {} 打印变量
println!("My name is {} and I am {} years old.", name, age);
// 使用位置参数
println!("{0} is {1} years old. {0} loves Rust.", name, age);
// 使用命名参数
println!("{name} is {age} years old.", name = "Bob", age = 25);
// 调试输出(用于打印结构体等复杂类型)
println!("{:?}", vec![1, 2, 3]);
}
注意 println! 的 ! 表示这是一个宏调用,而不是普通函数。宏在编译期展开,可以接受可变数量的参数,并且能对格式字符串进行静态检查。这是 Rust 宏系统的一个典型应用。
常见误区:初学者经常忘记 println! 末尾的感叹号,写成 println("...")。这会导致编译错误,因为 println 并不是一个已定义的函数。Rust 的宏调用必须使用感叹号。另外,println! 会自动在末尾添加换行符,如果你不想换行,应使用 print! 宏。
1.5 实战场景:编译并运行你的第一个程序
现在让我们完整地走一遍从创建到运行的流程,并观察每一步的输出。
步骤 1:创建项目
$ cargo new hello_world
Created binary (application) `hello_world` package
步骤 2:修改 main.rs
使用你喜欢的编辑器打开 src/main.rs,将内容替换为:
fn main() {
let project_name = "Rust 入门";
let days = 45;
println!("欢迎来到{}课程!", project_name);
println!("我们将在 {} 天内精通 Rust。", days);
println!("今天是第 1 天,加油!");
}
步骤 3:编译并运行
$ cargo run
Compiling hello_world v0.1.0 (/path/to/hello_world)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.35s
Running `target/debug/hello_world`
欢迎来到Rust入门课程!
我们将在 45 天内精通 Rust。
今天是第 1 天,加油!
观察输出,你会发现 Cargo 先编译了项目,然后自动运行生成的可执行文件。编译产物位于 target/debug/ 目录下。如果你只想编译不运行,可以使用 cargo build;如果想发布优化版本,使用 cargo build --release。
步骤 4:检查代码质量
Rust 生态提供了两个必备的代码质量工具:
$ cargo fmt # 自动格式化代码
$ cargo clippy # 静态检查,发现潜在问题
如果代码风格有问题,cargo fmt 会自动修正;cargo clippy 会给出改进建议。建议每次写完代码都运行这两个命令。
1.6 常见误区与总结复盘
在 Rust 入门阶段,初学者最容易遇到以下几个问题:
| 误区 | 现象 | 正确做法 |
|---|---|---|
| 忘记宏的感叹号 | 编译错误:cannot find function `println` | println! 和 print! 必须带 ! |
| 字符串拼接使用 + | 编译错误:cannot add &str to &str | 使用 format! 宏或 push_str 方法 |
| 忽略 Cargo.toml | 依赖管理混乱 | 所有依赖必须在 [dependencies] 中声明 |
| 直接运行 rustc | 无法管理依赖 | 使用 cargo 作为统一入口 |
| 不运行 cargo fmt | 代码风格不统一 | 养成每次提交前运行 fmt 的习惯 |
本章复盘:
- Rust 的核心优势是内存安全与高性能的完美结合,适合系统级开发。
- rustup 是安装和管理 Rust 工具链的标准方式,务必确保 PATH 配置正确。
- Cargo 是 Rust 的构建系统和包管理器,
cargo new创建项目,cargo run编译并运行。 - main 函数是程序入口,println! 是输出宏,支持格式化字符串。
- 项目结构遵循约定:Cargo.toml 描述项目,src/main.rs 存放源码。
学习建议:本章内容虽然基础,但请务必亲手敲一遍所有命令。Rust 是一门实践性极强的语言,只看不练很难真正理解所有权和借用等核心概念。建议在接下来的 44 天里,每天至少写 30 行 Rust 代码,保持手感。