本章要回答的三个问题:自定义类型怎么建、怎么初始化?枚举加模式匹配为什么被称为 Rust 的表达力核心?常用集合各适合什么案情?
前面章节的"物证"都是零散值。真实案件的证据要装袋、编目、入库:结构体是档案袋,把相关字段钉在一起;枚举是案由分类,把"互斥的几种情况"建成类型;集合是保管室,管理成批的堆上数据。本章还有一个暗线——每种数据结构都在与所有权法庭对接:字段持有所有权,移动语义随之而来。
| 节 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 4.1 结构体 | 固定字段怎么组织 | 方法语法、字段更新简写 |
| 4.2 枚举与模式匹配 | 互斥情况怎么建型 | Option 判例、match 穷尽性 |
| 4.3 集合类型 | 批量数据存哪 | 三大集合选型表、所有权联动 |
第 5 章给这些数据结构"立法":Trait 定义共同行为契约,泛型让一份结构适配多种类型。
数据结构章的报错集中在"产权"与"索引"两条线上,速查如下。
| 报错/现象 | 案情 | 修法方向 |
|---|---|---|
| E0382 + 更新语法 | ..old 移走了堆字段 |
逐字段 clone |
| E0502 + HashMap | get 之后 insert 借用重叠 | 改用 entry |
| E0600 | 字符串按整数索引 | chars().nth / 切片 |
| panic 切片越界 | 字节边界切开字符 | 用 char_indices 定边界 |
| E0004 | match 漏形态 | 补分支,慎用 _ |
面对新数据先问三个问题,答案基本决定容器与枚举的选型。一问"缺席是常态吗"——是则 Option 进字段类型,不要用空串、零值当哨兵;二问"形态可枚举吗"——可则上 enum,把非法状态设计成写不出来;三问"查找键是什么"——无键用 Vec,有键看是否要有序。这三问覆盖了业务建模八成的容器决策,剩下的两成(嵌套、图状结构)留到 trait 对象与智能指针章节再议。
本章的 struct 与 enum 还只是"数据卷宗",行为散落在各个使用现场。第 5 章的 trait 给卷宗配上一致的"操作规程":不同类型只要实现同一 trait,就能被同一段泛型代码处理。衔接点是 derive——#[derive(Debug)] 已经是 trait 系统的第一次出勤,下一章解释它背后到底发生了什么。
给任何业务实体建模前过一遍:缺席是常态吗(Option 进字段);形态可枚举吗(enum 替代布尔组合与魔法值);容器按哪个键访问(Vec/Deque/HashMap/BTreeMap 按序、键、有序键选)。三问答完,struct 与 enum 的形状基本自动浮现,剩下的只是 derive 清单与 impl 组织——而那是第 5 章的辖区。本章的判例速查表建议常备手边,字符串字节边界与 entry 改写两条在实际项目里出勤率最高。
一问:结构体更新语法 ..old 之后 old 还完整吗?答:Copy 字段完好、堆字段已移动,整体处于部分移动状态。二问:Vec<Option<T>> 与 HashMap<K,T> 表达缺席的差异?答:前者是"位置存在内容可能空",后者是"键不存在即缺席",语义分界在位置是否有意义。三问:HashMap 遍历输出顺序稳定吗?答:不稳定,需要有序遍历换 BTreeMap。三题对答如流,建模与容器的选型手感即告成型。