返回 Rust
Rust 2026-05-19

《Rust 程序设计语言(简体中文版)》前 38 页精读汇总

《Rust 程序设计语言(简体中文版)》前 38 页精读汇总

文档说明

本汇总覆盖 《Rust程序设计语言(简体中文版》PDF 前 38 页的全部内容,范围包括:

  • 页 1-4:封面与目录
  • 页 5:书籍版本与阅读资源说明
  • 页 6:前言
  • 页 7-10:简介
  • 页 11-22:第 1 章《入门指南》
  • 页 23-38:第 2 章《编写一个猜数字游戏》

一、前 38 页的整体结构与学习脉络

这 38 页承担的是全书的“起跑区”功能,作用可以概括为四层:

1. 先交代这本书是什么

书的前部先说明:

  • 这本书对应英文原版 The Rust Programming Language
  • 当前译本适配 Rust 1.90.0 及以上版本
  • 示例项目默认使用 Rust 2024 Editionedition = "2024"
  • 可在线阅读、离线阅读,也有交互版和社区译本

2. 再说明 Rust 为什么值得学

前言与简介反复强调 Rust 的核心价值主张:

  • 内存安全
  • 高性能
  • 强编译器反馈
  • 优秀工具链
  • 现代工程体验
  • 面向团队协作与长期维护

3. 然后告诉读者应该如何阅读本书

书中明确区分了两类章节:

  • 概念章节:系统讲语言机制
  • 项目章节:通过完整小项目把概念“跑起来”

4. 最后用一个微型项目建立 Rust 学习范式

第 2 章并不追求“讲完全部语法”,而是通过猜数字游戏让读者第一次接触:

  • let / mut
  • String
  • stdin / read_line
  • Result / expect
  • crate
  • match
  • Ordering
  • parse
  • loop / break / continue
  • 类型注解、遮蔽、外部依赖、Cargo 锁定版本

也就是说,Rust 的学习方式从一开始就不是“先背语法再写程序”,而是“借助编译器与项目实践逐步理解语言设计”。


二、逐页内容总览(页面级信息索引)

页码范围内容定位核心作用
1封面书名页
2-4目录给出全书章节地图,确认前 38 页覆盖到第 2 章结束
5版本与资源说明说明 Rust 版本、Edition、在线/离线/互动阅读资源
6前言强调 Rust 的社区、价值与发展定位
7-10简介说明 Rust 适合谁、本书适合谁、全书如何阅读
11第 1 章导言说明入门章目标
12-14安装rustup、平台安装、排错、更新、文档、离线依赖
15-18Hello, World!第一个 Rust 程序、编译运行、程序结构
19-22Hello, Cargo!Cargo 基础、项目布局、构建/运行/检查/发布
23-38猜数字游戏用完整小项目引入 Rust 的基础编程元素

三、封面、目录与版本信息(页 1-5)

3.1 页 1-4 的意义:前 38 页的知识边界

前 4 页虽然不是正文知识讲解,但非常重要,因为它们告诉我们:

  • 第 1 章从页 11 开始
  • 第 2 章从页 23 开始
  • 第 3 章从页 39 开始

这意味着:前 38 页完整覆盖了“入门环境 + 第一个项目教程”,尚未进入系统性的语法章节。

3.2 页 5 的关键信息

这一页提供了四类高价值元信息:

版本假设

本书假设:

  • 使用 Rust 1.90.0(2025-09-18 发布)或更高版本
  • 所有项目的 Cargo.toml 使用:
edition = "2024"

这意味着:

  • 示例理解应以 Rust 2024 Edition 为准
  • 读者不能默认本书对应旧版 Rust 语义

官方阅读方式

  • 英文原版 HTML:官方在线文档站点
  • 通过 rustup 安装的 Rust 自带英文离线版
  • 可用 rustup docs --book 打开本地文档

中文与社区资源

  • 简体中文译本有在线阅读地址
  • PDF 版本另行下载
  • 还有其他社区翻译版本

额外学习资源

书中特别推荐了一个具有测验、高亮、可视化功能的交互版 Rust Book。这说明本书并不把“阅读 PDF”当作唯一学习方式,而是鼓励交互式学习。


四、前言的核心思想(页 6)

前言并不讲语法,而是解释:Rust 为何在技术与社区层面都值得投入。

4.1 Rust 的增长并非偶然

前言认为 Rust 的崛起来自两类力量的叠加:

  • 技术层面的显著优势
  • 社区层面的全球协作与产业采用

4.2 Rust 的价值主张

前言把 Rust 的吸引力概括为一组同时成立的特性:

  • 内存安全
  • 高性能
  • 友好的编译器
  • 出色的工具链
  • 可靠性

这实际上概括了 Rust 的核心定位:尽量把“安全”和“底层控制”同时交给开发者。

4.3 Rust 不只是语言,更是“赋能型生态”

前言特别强调:

  • Rust 真正独特之处不只在特性集合
  • 更在于它试图让用户成功
  • 社区、项目维护、倡导方式都围绕“赋能使用者”展开

4.4 Rust 已成为全球化、可信赖的语言

前言指出:

  • Rust 项目得到 Rust Foundation 支持
  • Rust 被持续投入、维护、治理
  • 语言的发展目标是安全、稳定、可持续

4.5 本书的定位

这本书不仅是语法/库说明书,更是一份“进入 Rust 社区”的邀请。它面向:

  • 第一次接触 Rust 的经验开发者
  • 想进一步精进的 Rust 使用者

4.6 前言的精华提炼

一句话概括前言:

Rust 被描绘成一门兼顾性能、安全、工程实践与社区文化的现代系统编程语言,而阅读本书意味着不仅学习语法,也进入一种更强调质量与设计审慎的软件文化。


五、简介的完整提炼(页 7-10)

5.1 Rust 试图解决的根本矛盾

简介一开始就提出:传统语言设计里,往往需要在以下两类能力之间做权衡:

  • 高层工程体验
  • 底层控制能力

Rust 的目标是挑战这种对立:

  • 让开发者保有对内存等底层细节的控制权
  • 同时尽量减少这类控制带来的繁琐负担

这相当于给出了本书后续全部内容的总纲。

5.2 Rust 适合哪些人

简介对 Rust 的潜在读者作了非常清晰的分群。

开发者团队

Rust 适合团队的原因包括:

  • 底层代码中的微妙错误很多
  • 在其他语言中,这类错误往往依赖测试和资深审查才能发现
  • Rust 编译器在编译期就扮演“守门人”角色
  • 连并发错误也会被编译器强力约束

因此,团队可把更多精力放在业务逻辑而不是追 bug 上。

同时,简介还强调 Rust 的现代开发工具:

  • Cargo:依赖管理与构建工具
  • Rustfmt:代码格式统一
  • Rust Language Server:提供补全与内联错误信息

注意:简介页使用了“Rust Language Server”这一表述;而第 1 章后文又明确提到 rust-analyzer。就前 38 页文本本身而言,两种表述都出现了。

学生

Rust 适合学习系统概念,因为:

  • 社区欢迎提问
  • 很多人借 Rust 学习操作系统等主题
  • 本书与社区内容试图让系统概念更易理解

公司

Rust 已被用于生产环境中的多种场景,包括:

  • 命令行工具
  • Web 服务
  • DevOps 工具
  • 嵌入式设备
  • 音视频处理
  • 加密货币
  • 生物信息学
  • 搜索引擎
  • IoT 应用
  • 机器学习
  • Firefox 浏览器的重要组成部分

开源开发者

Rust 不只欢迎“使用者”,也欢迎构建:

  • 语言本身
  • 社区
  • 工具链
  • 库生态

的贡献者。

重视速度与稳定性的开发者

这一类读者的关注点有两个:

  • 程序运行速度
  • 开发迭代时的稳定性

书中强调:

  • Rust 编译器的检查帮助开发者安心重构
  • 通过“零成本抽象(zero-cost abstractions)”追求:高级抽象不应带来额外运行时成本
  • Rust 想让“安全代码”和“快速代码”尽可能同时成立

5.3 本书适合哪些人

简介明确假设:

  • 读者已经学过至少一种编程语言
  • 但不要求特定语言背景
  • 不会花大量篇幅解释“什么是程序设计”或“如何培养编程思维”

因此,这本书是Rust 入门书,但不是零编程基础入门书

5.4 如何阅读本书

两类章节

  • 概念章节:介绍 Rust 某一领域
  • 项目章节:通过程序把前面知识串起来

章节安排逻辑

简介对全书做了章节导航,前 38 页之内最关键的是:

  • 第 1 章:安装、Hello World、Cargo
  • 第 2 章:猜数字游戏,先做项目、后补细节

并给出阅读建议:

  • 想快速上手,可直接读第 2 章
  • 想更稳扎稳打,也可先跳到第 3 章学基础,再回来看项目

编译器报错是学习材料

本书特别提醒:

  • 书中有些代码故意不能编译
  • 目的是让读者学习 Rust 编译器的诊断信息
  • 学会读错误信息,是学习 Rust 的关键组成部分

Ferris 图示含义

书中使用 Ferris 图示标记三类非正常示例:

  • 代码无法通过编译
  • 代码会 panic!
  • 代码运行结果不符合预期

这实际上建立了一个非常重要的阅读约定:不要默认书中每一段代码都能直接运行。

源码与译本仓库

简介末尾还说明:

  • 本书源码可在 GitHub 获取
  • 中文译本也有 GitHub 仓库,可提交 Issue / PR

5.5 简介的核心精华

简介的真正重点不是“目录说明”,而是确立了三条方法论:

  1. Rust 追求同时拥有安全、性能、生产力与可维护性。
  2. 学习 Rust 不能只背语法,必须学会读编译器错误。
  3. 本书的最佳阅读方式是概念学习与项目实践相互穿插。

六、第 1 章《入门指南》完整提炼(页 11-22)

6.1 本章目标(页 11)

第 1 章只做三件事:

  • 安装 Rust
  • 编写一个打印 Hello, world! 的程序
  • 使用 Rust 的包管理器和构建系统 cargo

这章的本质不是讲语言本身,而是建立工具链使用习惯


6.2 安装 Rust(页 12-14)

6.2.1 官方推荐安装方式:rustup

rustup 是:

  • Rust 版本管理器
  • 相关工具安装器
  • 官方推荐入口

书中默认读者通过 rustup 获取最新稳定版 Rust。

Linux / macOS 安装命令

curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

含义:下载脚本并执行 rustup 安装流程。

6.2.2 链接器与 C 编译器依赖

Rust 编译输出最终需要链接成可执行文件,因此需要链接器。书中特别提醒:

  • 若遇到 linker 错误,需要安装 C 编译器
  • 因为 C 编译器通常自带链接器
  • 某些 Rust 包也依赖 C 代码,因此系统里有 C 工具链本身就很常见

macOS

xcode-select --install

Linux

  • 应根据发行版文档安装 GCC 或 Clang
  • Ubuntu 示例:build-essential

6.2.3 Windows 安装重点

Windows 使用官方安装页面安装 Rust 时,过程中会提示安装 Visual Studio;原因是:

  • 需要链接器
  • 需要本地库
  • 需要编译环境支持

6.2.4 Rust 的稳定性承诺

书中明确说明:

  • 使用较新的稳定版 Rust,书中能编译的示例通常也应继续能编译
  • 错误信息与警告文本可能变化
  • 但总体内容应保持适配

这体现了 Rust 的稳定发布策略。

6.2.5 命令行标记规则

全书命令展示约定:

  • $:终端提示符,不用输入
  • >:PowerShell 示例使用
  • 不带提示符的行:通常是命令输出

这条规则对后续整本书阅读都重要。

6.2.6 安装完成后的验证

rustc --version

预期输出包含:

  • 版本号
  • commit hash
  • commit 日期

若失败,应检查 PATH:

Windows CMD

echo %PATH%

PowerShell

echo $env:Path

Linux / macOS

echo $PATH

6.2.7 更新与卸载

更新

rustup update

卸载

rustup self uninstall

6.2.8 本地文档

rustup doc

作用:打开离线文档。

书中特别建议:

  • 对标准库类型或函数不确定时,应主动查 API 文档

这说明 Rust 学习高度依赖官方文档与类型文档。

6.2.9 编辑器与 IDE

本书不绑定特定工具。原则上:

  • 任何文本编辑器都可以写 Rust
  • 许多编辑器/IDE 都内置支持
  • Rust 团队持续强化 IDE 体验
  • 第 1 章注记特别提到 rust-analyzer

6.2.10 离线使用本书

如果后续示例依赖外部 crate,想离线运行,可以先缓存依赖:

cargo new get-dependencies
cd get-dependencies
cargo add rand@0.8.5 trpl@0.2.0

之后:

  • 即使不保留该项目目录也没关系
  • 后续 cargo 命令可配合 --offline 使用缓存版本

这一节的核心结论

安装部分真正建立的不是“会装 Rust”,而是完整的基础工作环境观念

  • rustup 管版本
  • rustc --version 验证工具链
  • 用 API 文档解决标准库疑问
  • 用依赖缓存与 --offline 适应离线环境
  • 认识链接器和 C 工具链在 Rust 世界中的现实地位

6.3 Hello, World!(页 15-18)

6.3.1 项目目录与文件命名

书中建议:

  • 在 home 目录下建立 projects 目录
  • 各个 Rust 练习与项目放入其中

示例目录创建方式:

mkdir ~/projects
cd ~/projects
mkdir hello_world
cd hello_world

Windows 则使用 %USERPROFILE%

Rust 文件命名约定:

  • 扩展名必须是 .rs
  • 多词文件名使用下划线分隔
  • 推荐 hello_world.rs,不推荐 helloworld.rs

6.3.2 第一个程序的核心代码

最基本的 Rust 程序由两部分构成:

  • fn main():程序入口
  • println!:输出宏

其最小结构可概括为:

fn main() {
    println!("Hello, world!");
}

6.3.3 用 rustc 编译与运行

rustc main.rs
./main

Windows 运行方式:

.\main

6.3.4 程序结构解析

书中对这个示例提炼了三个关键语法点:

main 函数

  • 每个可执行 Rust 程序都从 main 开始
  • () 表示无参数
  • {} 包裹函数体

println! 是宏而不是函数

  • 结尾有 !
  • 说明它是宏调用
  • 宏可扩展语法、生成代码
  • 宏与普通函数不完全遵循同一套规则

字符串字面值与分号

  • "Hello, world!" 是字符串字面值
  • 分号 ; 结束一条表达式,使下一条表达式可以开始
  • Rust 中大多数代码行以分号结束

6.3.5 rustc 工作流与可执行文件

编译成功后:

  • Linux/macOS:得到 main
  • Windows:得到 main.exe,并伴随调试信息文件 main.pdb

6.3.6 Rust 是预先编译语言(ahead-of-time compiled)

书中专门拿 Ruby / Python / JavaScript 做对比,说明 Rust 的一个工程特征:

  • Rust 程序先编译成可执行文件
  • 把可执行文件交给别人,对方不需要安装 Rust 也能运行
  • 这与解释型/运行时依赖型语言有明显区别

6.3.7 从 rustc 过渡到 Cargo

这一节最后明确指出:

  • rustc 适合简单程序
  • 一旦项目变复杂、需要依赖和结构管理,就应转向 Cargo

这一节的精华

Hello World 的真正教学目标不是打印一句话,而是让读者第一次建立 Rust 的基本思维:

  • 程序从 main 开始
  • 输出常用宏 println!
  • Rust 先编译后运行
  • 简单程序可直接用 rustc
  • 复杂项目应尽快采用 Cargo

6.4 Hello, Cargo!(页 19-22)

6.4.1 Cargo 的定位

Cargo 是 Rust 的:

  • 构建系统
  • 包管理器
  • 依赖协调器
  • 项目脚手架工具

书中强调:大多数 Rust 项目都使用 Cargo。

6.4.2 检查 Cargo 是否可用

cargo --version

6.4.3 创建项目

cargo new hello_cargo
cd hello_cargo

创建结果包括:

  • Cargo.toml
  • src/main.rs
  • Git 仓库
  • .gitignore

若不希望默认 VCS 行为,可用 --vcs 参数调整。

6.4.4 Cargo.toml 的关键信息

最基础的配置如下:

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]

这一页顺带引入了几个核心概念:

  • Cargo.toml 使用 TOML 格式
  • [package] / [dependencies] 是 section
  • Rust 中的代码包称为 crate
  • 依赖配置集中在 [dependencies]

6.4.5 Cargo 的项目布局哲学

Cargo 要求:

  • 源码放在 src/
  • 项目根目录放 README、license、配置等非源码内容

这体现了 Cargo 强调工程化目录规范。

6.4.6 将现有项目转换为 Cargo 项目

如果一开始不是用 Cargo 创建项目,可以:

  • 把源码移入 src
  • 创建 Cargo.toml
  • 或使用:
cargo init

6.4.7 构建、运行、检查

构建

cargo build

默认输出放在:

  • target/debug/

运行

cargo run

特点:

  • 一条命令完成构建 + 运行
  • 如果源码未变化,Cargo 不会重复编译

仅做编译检查

cargo check

特点:

  • 检查代码是否能编译
  • 不生成可执行文件
  • 因此比 cargo build 更快

6.4.8 Cargo.lock 与可重现构建

书中首次引入一个极其重要的工程概念:

  • 第一次构建时生成 Cargo.lock
  • 它记录依赖的精确版本
  • 之后构建优先使用锁定版本
  • 这样可保证可重现构建(reproducible build)

同时明确说明:

  • Cargo.lock 通常应提交到版本控制
  • 不应手工编辑
  • Cargo 会自动维护它

6.4.9 发布构建

cargo build --release

效果:

  • 启用优化
  • 输出到 target/release/
  • 适合正式发布或做性能基准测试

书中同时说明开发与发布 profile 的差别:

  • dev:编译更快,适合频繁迭代
  • release:运行更快,适合交付

6.4.10 “把 Cargo 当作习惯”

这是本节最重要的一句话之一。含义是:

  • 即使小项目也可练习 Cargo 流程
  • 一旦项目增长、出现多文件或依赖,Cargo 的价值立刻放大

这一节的精华

第 1 章真正要读者形成的习惯不是“知道 Cargo 存在”,而是:

从 Rust 学习的起点开始,就把项目、依赖、构建、运行、检查、发布、锁版本这些工程流程视为编程的一部分,而不是附属动作。


七、第 2 章《编写一个猜数字游戏》完整提炼(页 23-38)

第 2 章是前 38 页的重点,因为它把前面安装和工具链内容真正“接上了代码”。

7.1 本章的教学目标(页 23)

本章不是讲透 Rust,而是先用一个小游戏快速引入:

  • let
  • match
  • 方法(method)
  • 关联函数(associated function)
  • 外部 crate

游戏规则

  • 程序生成 1 到 100 之间的随机整数
  • 用户输入猜测值
  • 程序提示“太小”或“太大”
  • 猜中则输出祝贺并退出

这章的设计非常重要:先搭一个能工作的程序,再借程序逐步拆解概念。


7.2 新建项目(页 23)

cargo new guessing_game
cd guessing_game
cargo run

书中借此再次强化:

  • 新项目默认是一个 Hello, world!
  • cargo run 适合快速迭代验证

7.3 处理一次猜测:输入、变量、字符串、引用、结果类型(页 24-27)

这是第一个完整的“Rust 小闭环”。

7.3.1 引入输入库

use std::io;

含义:

  • io 来自标准库 std
  • 若某类型/函数不在 prelude 中,就要显式 use

7.3.2 程序入口与输出提示

println!("Guess the number!");
println!("Please input your guess.");

作用:

  • 向用户说明游戏开始
  • 请求输入

7.3.3 变量默认不可变,mut 明确声明可变性

let mut guess = String::new();

这行代码同时引入多个关键信息:

  • let 用于绑定变量
  • Rust 变量默认不可变
  • mut 让变量可变
  • String::new() 创建一个新的空字符串

书中还借 apples / bananas 示例强调:

  • 不可变是默认立场
  • 可变性必须显式声明

7.3.4 String 的意义

这里的 String 被介绍为:

  • 标准库提供的字符串类型
  • UTF-8 编码
  • 可增长的文本块

7.3.5 关联函数

String::new() 中的 :: 表示:

  • newString 类型上的关联函数
  • 不是某个具体实例上的方法

7.3.6 从标准输入读取数据

io::stdin().read_line(&mut guess)

拆开理解:

  • stdin() 返回标准输入句柄
  • read_line(...) 从终端读取一行
  • 读取到的内容会追加到字符串中,而不是覆盖

7.3.7 引用与可变引用(这里只作初步引入)

&mut guess

书中在这里没有全面展开所有权系统,但先给出一个非常关键的直觉:

  • & 表示引用
  • 引用允许代码访问某处数据,而不复制数据
  • 引用默认也是不可变的
  • 因为 read_line 需要修改字符串,所以必须传 &mut guess

7.3.8 Resultexpect

.expect("Failed to read line")

这一步引入了 Rust 错误处理的最基本接口:

  • read_line 返回 Result
  • Result 是枚举
  • 成功分支是 Ok
  • 失败分支是 Err
  • expect(...)Err 时让程序崩溃,并输出指定消息
  • 若为 Ok,则提取成功值并返回

书中还展示了一个重要编译器警告:如果你忽略 Result,编译器会提示你“这个返回值必须被使用”,因为它可能包含错误。

这体现出 Rust 的设计哲学:错误不能被悄悄忽略。

7.3.9 println! 的格式化占位符

println!("You guessed: {guess}");

这里介绍了两种格式化写法:

  • {guess}:直接内嵌变量名
  • {}:留空占位,再在后面传表达式

示例:

println!("x = {x} and y + 2 = {}", y + 2);

7.3.10 第一阶段完成后的意义

这一小段代码已经让读者接触到:

  • 标准库导入
  • 可变变量
  • String
  • 关联函数
  • 方法链
  • 可变引用
  • Result
  • expect
  • 格式化输出

这也是本章的教学风格:同一个小程序不断增量升级,每一步只增加少量概念。


7.4 生成秘密数字:外部 crate、SemVer、Cargo.lock(页 27-31)

7.4.1 Rust 标准库不直接提供随机数

书中明确说:

  • 标准库本身不包含随机数功能
  • 但官方生态中有 rand crate

这让读者第一次接触到:Rust 的能力经常由“标准库 + crates.io 生态”共同构成。

7.4.2 什么是 crate

书中在这里区分了两类 crate:

  • 二进制 crate:生成可执行文件
  • 库 crate:供其他程序复用,不能独立运行

当前项目 guessing_game 是二进制 crate;rand 是库 crate。

7.4.3 添加依赖

Cargo.toml 中加入:

[dependencies]
rand = "0.8.5"

7.4.4 语义化版本(SemVer)

书中非常明确地解释了:

  • 0.8.5 实际等价于 ^0.8.5
  • 表示允许使用 >=0.8.5<0.9.0 的版本
  • 这样既能获得兼容补丁更新,又不越过潜在破坏性大版本边界

这是一条非常关键的工程知识。

7.4.5 Cargo 在背后做了什么

第一次 cargo build 时,Cargo 会:

  1. 更新 crates.io 索引
  2. 解析依赖图
  3. 下载所需 crate
  4. 先编译依赖
  5. 再编译当前项目

7.4.6 Cargo 的复用与增量构建

书中强调两种复用:

  • 依赖没变,就不会重复下载与重编译依赖
  • 源码没变,就不会重新构建当前项目

这说明 Cargo 并不是“每次都全量来一遍”。

7.4.7 Cargo.lock 的真实意义

在这一页,Cargo.lock 的作用被讲得非常透彻:

  • 第一次解析出的精确版本会写入锁文件
  • 之后构建复用锁文件中的版本
  • 这样保证团队成员或未来时间点重新构建时,得到相同依赖组合

这是可重现构建的基础。

7.4.8 更新依赖

cargo update

这一节说明:

  • cargo update 会忽略原有 Cargo.lock 重新计算允许范围内的最新版本
  • 但仍受 Cargo.toml 的版本约束限制
  • 如果要跨出约束范围,必须手改 Cargo.toml

7.4.9 在代码中使用 rand

关键代码结构:

use rand::Rng;
let secret_number = rand::thread_rng().gen_range(1..=100);

其中包含三个高价值点:

use rand::Rng;

  • Rng 是 trait
  • 为了调用对应方法,trait 必须先进入作用域

thread_rng()

  • 获取当前线程局部的随机数生成器
  • 由操作系统提供种子

gen_range(1..=100)

  • 根据范围表达式生成随机数
  • 1..=100闭区间,包含上下边界

7.4.10 cargo doc --open

这一页还顺手强调了 Rust 生态的文档文化:

  • 不必“凭空猜”某个 crate 如何使用
  • 运行 cargo doc --open 可以本地构建并查看依赖文档

这一节的精华

这里真正建立的是 Rust 生态使用方式:

Rust 项目默认不是“只写源文件”,而是“通过 Cargo 管理项目,通过 crates.io 复用社区库,通过 SemVer 控制兼容范围,通过 Cargo.lock 保证构建可重现”。


7.5 比较输入与答案:强类型、枚举、匹配、编译错误教学(页 31-34)

7.5.1 使用 Orderingcmp

书中加入:

use std::cmp::Ordering;
match guess.cmp(&secret_number) {
    Ordering::Less => println!("Too small!"),
    Ordering::Greater => println!("Too big!"),
    Ordering::Equal => println!("You win!"),
}

这里第一次系统引出:

  • Ordering 是枚举
  • 有三个成员:LessGreaterEqual
  • cmp 用于比较两个值
  • match 根据不同枚举成员进入不同分支

7.5.2 match 的教学作用

书中给出的解释很重要:

  • match 由多个 arm 构成
  • 每个 arm 包含模式与对应执行代码
  • Rust 会检查值与哪个模式匹配
  • 一旦匹配成功,执行对应分支并停止继续匹配

这实际上是让读者第一次接触 Rust 的代数数据类型 + 模式匹配思维方式。

7.5.3 故意触发编译错误:字符串不能直接和整数比较

书中紧接着展示一个故意不能编译的版本,并给出 E0308 mismatched types 错误。核心原因是:

  • guess 当前是 String
  • secret_number 是整数
  • Rust 是静态强类型语言
  • 不会自动把字符串和整数拿来比较

这是第 2 章非常关键的一步:用真实编译错误教学,而不是回避错误。

7.5.4 parse、类型注解与遮蔽

修正方式:

let guess: u32 = guess.trim().parse().expect("Please type a number!");

这一行一次性引入多个核心概念。

trim()

  • 去掉首尾空白
  • 特别是处理 read_line 读入的换行符
  • Windows 中还可能有 \r\n

parse()

  • 把字符串解析成其他类型
  • 这里要解析成整数

类型注解 : u32

  • 告诉 Rust 目标数值类型
  • 同时让与 secret_number 的比较类型一致

遮蔽(shadowing)

书中明确指出:

  • 这里重新定义了一个同名 guess
  • guess 遮蔽旧 guess
  • 这是常见做法:把值从一种类型变换到另一种类型,同时复用变量名

parse 返回 Result

  • 可能成功得到 Ok(num)
  • 也可能失败得到 Err(...)
  • 这里先用 expect 粗暴处理失败情况

这一节的精华

这一部分把 Rust 的两个关键气质展现得非常清楚:

  1. Rust 要求类型明确,不做含糊的隐式转换。
  2. 编译错误不是障碍,而是学习语言规则的入口。

7.6 使用循环让游戏真正可玩(页 34-36)

7.6.1 loop:无限循环

书中使用 loop 把“读输入 -> 解析 -> 比较”的整段逻辑包起来,形成可重复猜测的版本。

这一步引入:

  • loop 创建无限循环
  • 用户可以多次输入

7.6.2 问题暴露:如何退出

书中有意展示一个中间状态:

  • 程序能无限猜测
  • 但暂时没有优雅退出方式
  • 用户只能 ctrl-C 或输入非法值导致程序崩溃

这是一种典型的“渐进式教程写法”:先得到可运行版本,再识别体验缺陷并优化。

7.6.3 break:猜中后退出循环

书中把 Ordering::Equal 分支改为:

Ordering::Equal => {
    println!("You win!");
    break;
}

含义:

  • 猜中时退出 loop
  • 因为这个循环已经是 main 的尾部,所以退出循环就等于结束程序

7.7 处理无效输入:从“崩溃式”到“恢复式”错误处理(页 36-38)

这是第 2 章最重要的升级点之一。

7.7.1 从 expect 改成 match

书中把:

guess.trim().parse().expect(...)

改为:

let guess: u32 = match guess.trim().parse() {
    Ok(num) => num,
    Err(_) => continue,
};

7.7.2 含义

  • 如果解析成功:取出数字 num
  • 如果解析失败:直接 continue
  • 本轮循环剩余部分跳过,进入下一轮重新输入

7.7.3 通配模式 _

书中专门说明:

  • _ 是通配值
  • 表示“我不关心 Err 里具体装的是什么”

7.7.4 这一步的重要性

这是前 38 页里一个非常有代表性的 Rust 思维转折:

  • 一开始用 expect,方便快速得到原型
  • 随后改成 match,实现更合理的错误处理

也就是说,第 2 章在潜移默化地传达一种开发流程:

先让程序工作,再逐步把“能跑”提升为“好用、健壮、符合语义”。

7.7.5 最终程序的逻辑闭环

第 2 章最终版程序的算法流程可以概括为:

  1. 打印游戏开始信息
  2. 生成 1..=100 的随机秘密数字
  3. 进入无限循环
  4. 提示输入
  5. 读取一行到 String
  6. trim + parse 转为 u32
  7. 若解析失败,continue
  8. 若成功,打印猜测值
  9. cmp 比较
  10. match 输出“太小 / 太大 / 猜中”
  11. 猜中则 break

这一节的精华

第 2 章用一个小游戏,已经把 Rust 最关键的几种基础能力串成了一个完整工程闭环:

  • 输入
  • 输出
  • 可变状态
  • 类型转换
  • 外部依赖
  • 枚举与匹配
  • 循环控制
  • 失败分支处理

八、前 38 页中出现的重要术语与概念清单

下面这份清单适合作为“前 38 页知识地图”。

工具链与工程术语

  • rustup:Rust 版本与工具管理器
  • rustc:Rust 编译器
  • Cargo:构建系统与包管理器
  • crate:Rust 代码包
  • dependency:依赖
  • Cargo.toml:项目配置文件
  • Cargo.lock:精确依赖锁文件
  • crates.io:Rust 开源库发布平台
  • SemVer:语义化版本
  • debug build / release build:开发构建 / 发布构建

语言与语法术语

  • fn main():程序入口函数
  • 宏(macro):如 println!
  • 字符串字面值:如 "Hello, world!"
  • String:可增长 UTF-8 字符串
  • 变量默认不可变
  • mut:可变绑定
  • 关联函数(associated function):如 String::new()
  • 方法(method):如 .read_line(...).trim().parse()
  • 引用(reference):&T
  • 可变引用:&mut T
  • Result:表示成功或失败的枚举
  • Ok / ErrResult 两个分支
  • expect:失败则 panic,成功则取值
  • trait:行为接口;如 Rng
  • 枚举(enum):如 OrderingResult
  • match:模式匹配分支
  • pattern / arm:模式 / 分支
  • 遮蔽(shadowing):同名新变量覆盖旧变量
  • loop:无限循环
  • break:退出循环
  • continue:进入下一轮循环
  • range expression:范围表达式,如 1..=100
  • panic:程序因严重错误而终止

九、前 38 页最值得掌握的“精华”

如果只抓核心,不抓细枝末节,那么这 38 页最值得记住的是以下几点。

9.1 Rust 学习从“工具链”开始,而不是从语法表开始

这本书一上来先讲:

  • 安装
  • 文档
  • 编译器
  • Cargo
  • 依赖管理
  • 项目目录

这说明 Rust 把“工程实践”视为语言学习的一部分。

9.2 Cargo 不是附加工具,而是 Rust 的默认工作方式

前 38 页反复强化一个观念:

  • 小程序能用 rustc
  • 真正的 Rust 开发应该尽快用 Cargo

因为 Cargo 同时管理:

  • 项目结构
  • 依赖
  • 构建流程
  • 运行
  • 锁版本
  • 发布优化

9.3 Rust 倾向于显式,而不是隐式猜测

典型表现:

  • 字符串不能直接和整数比较
  • parse() 后必须给出足够的类型信息
  • 错误值不能默认悄悄忽略
  • 可变性必须显式声明

9.4 编译器是“合作者”,不是“拦路者”

简介和第 2 章共同传达一个关键信念:

  • 编译器报错本身就是教学材料
  • 通过报错学习规则,是 Rust 的正常学习路径

9.5 错误处理从第一天就被纳入语言主线

哪怕在最简单的输入程序里,也已经出现:

  • Result
  • Ok / Err
  • expect
  • match
  • 忽略错误会被警告

这说明 Rust 从入门开始就把“错误是显式状态”这一思想灌输给读者。

9.6 第 2 章本质上是一个“语言缩影”

猜数字游戏虽然小,却已经折射出 Rust 的核心风格:

  • 用类型约束行为
  • 用枚举表达状态
  • match 覆盖分支
  • 用 Cargo 管项目
  • 用 crate 扩展能力
  • 用锁文件保证可重现构建
  • 用循环与控制流表达程序骨架

十、适合复习的命令速查表(前 38 页)

10.1 安装与环境

rustc --version
rustup update
rustup self uninstall
rustup doc

10.2 Linux / macOS 安装

curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
xcode-select --install

10.3 项目创建与运行

cargo new hello_cargo
cargo init
cargo build
cargo run
cargo check
cargo build --release

10.4 离线依赖缓存

cargo new get-dependencies
cd get-dependencies
cargo add rand@0.8.5 trpl@0.2.0

10.5 依赖与文档

cargo update
cargo doc --open

十一、适合建立长期理解的结论

结论 1:Rust 的“入门”本身就是工程化入门

前 38 页并没有把 Rust 教成“写几行代码就结束”的玩具语言,而是从第一章就把:

  • 编译器
  • 包管理
  • 目录结构
  • 依赖
  • 文档
  • 构建模式
  • 锁定版本

全部纳入基本功。

结论 2:Rust 强调“让正确做法更自然”

mutResultCargo.lockmatch,都体现出同一种设计倾向:

  • 要你显式表达意图
  • 让风险暴露得更早
  • 让工程结果更可预测

结论 3:第 2 章并不是小游戏教程,而是一个教学设计样板

它通过一个极小项目,把后续章节会系统展开的内容提前“见一面”,包括:

  • 变量与可变性
  • 类型与类型转换
  • 枚举与模式匹配
  • 错误处理
  • 控制流
  • crate 与 Cargo
  • 引用

所以第 2 章真正的价值不在游戏本身,而在于:

它让读者第一次体验到 Rust 编程究竟是怎样一种过程。


十二、一句话总评

前 38 页完成了三件最重要的事:先让你搭好 Rust 的工程环境,再让你理解这门语言的价值定位,最后用一个小而完整的项目让你亲手感受 Rust 的核心编程风格。

如果把这 38 页的精华压缩成一句学习建议,那就是:

学 Rust 时,不要把“编译器报错、Cargo 工作流、依赖版本、错误处理、类型约束”看成额外负担;这些东西本身就是 Rust 的入门内容,也是 Rust 之所以强大的原因。