章节目录

结构体、枚举、模式匹配与建模

本章目标

这一章学习 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) 方便,但克隆大对象可能有成本。
  • 字段公开会让外部依赖内部结构,后续修改更难。

练习

  1. 定义 HttpStatus 枚举,包含 OkNotFoundInternalError
  2. 写函数把 HttpStatus 转成状态码。
  3. 定义 Chapter 结构体,保存 slug、title、part。
  4. match 打印不同路由。

造轮子任务

造一个迷你路由枚举 Route,实现 parse_route(path: &str) -> Route。要求支持 //docs/docs/{slug}/post/{id}。这会让你理解框架路由的本质只是“字符串到枚举”的转换。

小结

结构体让数据成形,枚举让状态受控,模式匹配让分支完整。Rust 的建模能力非常适合工程架构,因为它把很多约定变成编译器能检查的类型。