结构体、枚举、模式匹配与建模
本章目标
这一章学习 Rust 如何表达业务概念。结构体适合描述“一个东西有哪些字段”,枚举适合描述“一个值可能是哪几种情况”,模式匹配负责安全地拆开这些形状。
它是什么
结构体:
struct Post {
id: String,
title: String,
body: String,
}
枚举:
enum Route {
Home,
Docs(String),
Post(String),
NotFound,
}
结构体聚合字段,枚举表达选择。
为什么需要
程序不是只处理字符串和数字。一个博客系统里有文章、请求、响应、章节、错误。把这些概念建模成类型,代码会更可靠。
如果你用裸字符串表示所有路径,任何函数都可能传错。如果你用 Route 枚举表示路由,编译器能强迫你处理每种情况。
怎么使用
let route = Route::Docs("00-preface".to_string());
match route {
Route::Home => println!("首页"),
Route::Docs(slug) => println!("文档章节:{slug}"),
Route::Post(id) => println!("文章:{id}"),
Route::NotFound => println!("404"),
}
match 必须穷尽所有可能,这能避免漏处理分支。
逐行解释
#[derive(Debug, Clone)]
struct Chapter {
slug: String,
title: String,
}
#[derive(Debug, Clone)]让编译器自动生成调试打印和克隆能力。struct Chapter定义一个章节类型。slug: String保存 URL 中使用的标识,比如00-preface。title: String保存页面显示标题。- 每个字段都有名字和类型。
- 字段默认私有,是否公开要根据模块边界决定。
结构体让“章节”从散落的两个字符串变成一个明确概念。
常见坑
- 枚举分支可以携带数据,不只是数字常量。
match分支必须覆盖所有情况,可以用_兜底,但不要滥用。derive(Clone)方便,但克隆大对象可能有成本。- 字段公开会让外部依赖内部结构,后续修改更难。
练习
- 定义
HttpStatus枚举,包含Ok、NotFound、InternalError。 - 写函数把
HttpStatus转成状态码。 - 定义
Chapter结构体,保存 slug、title、part。 - 用
match打印不同路由。
造轮子任务
造一个迷你路由枚举 Route,实现 parse_route(path: &str) -> Route。要求支持 /、/docs、/docs/{slug}、/post/{id}。这会让你理解框架路由的本质只是“字符串到枚举”的转换。
小结
结构体让数据成形,枚举让状态受控,模式匹配让分支完整。Rust 的建模能力非常适合工程架构,因为它把很多约定变成编译器能检查的类型。