Rustlings enums 章节精讲:用枚举变体与模式匹配表达代数数据类型
Rustlings enums 章节精讲用枚举变体与模式匹配表达代数数据类型【免费下载链接】rustlings:crab: Small exercises to get you used to reading and writing Rust code!项目地址: https://gitcode.com/gh_mirrors/ru/rustlingsRust 的枚举enum是一种枚举出所有可能取值的类型定义机制Rustlings 的 enums 章节将其定位为与函数式语言F#、OCaml、Haskell中代数数据类型ADT相当的核心特性并强调其与模式匹配pattern matching配合使用的价值。本篇围绕 exercises/08_enums 下的三道递进式练习enums1、enums2、enums3展开从定义最简单的单元变体到为变体携带数据结构体式、元组式两种形式再到用match对枚举进行解构分发最后结合 Rustlings 工具链的run/hint机制说明如何在本仓库中实际完成并验证这一章节。为什么 Rust 的枚举与其他语言不同章节 README 开篇即指出枚举是许多语言都具备的特性但各语言的枚举能力参差不齐Rust 的枚举最接近函数式语言的代数数据类型。其关键差异在于Rust 的每个变体variant可以携带不同的数据并且编译器强制对枚举做穷尽处理。对照 exercises/README.md 中的练习到书章节映射表enums 对应 The Rust Book 的 §6枚举与模式匹配与 §19.3模式语法这也解释了本章练习的组织方式——先认识变体形态再落到模式匹配上。Rustlings 仓库为每个练习同时维护了两份文件待完成的练习文件exercises/下含TODO占位与参考解答solutions/下。例如 enums1 的练习与解答分别是 exercises/08_enums/enums1.rs 和 solutions/08_enums/enums1.rs这种题目 标准答案的结构本身就是理解每个知识点的最佳路径。enums1单元变体与#[derive(Debug)]练习文件 enums1.rs 给出了骨架#[derive(Debug)] enum Message { // TODO: Define a few types of messages as used below. } fn main() { println!({:?}, Message::Resize); println!({:?}, Message::Move); println!({:?}, Message::Echo); println!({:?}, Message::ChangeColor); println!({:?}, Message::Quit); }main函数用{:?}调试格式打印了五个变体因此需要补全的正是这五个不携带数据的单元变体。标准解答 为#[derive(Debug)] enum Message { Resize, Move, Echo, ChangeColor, Quit, }这里有两个值得注意的实现细节#[derive(Debug)]的必要性{:?}格式化要求类型实现Debugtrait。单元变体枚举无法手动感知内容derive宏会在编译期为Message自动生成Debug实现直接打印变体名如Resize。若移除deriveprintln!({:?}, Message::Resize)会因Message未实现Debug而编译失败。单元变体unit-like variant的语义这种形态等价于 C 的枚举常量仅表示某件事发生了不携带任何状态。这也是为什么 info.toml 中该练习的 hint 只有一句 No hints this time ;)见 rustlings-macros/info.toml 第 434 行附近——它被设计成本章的热身。用 Rustlings 运行与查看提示的命令命令定义见 src/cli.rs 中的Command枚举rustlings run enums1 # 编译并运行该练习通过后标记为 done rustlings hint enums1 # 输出该练习的提示enums2让变体携带数据——三种变体形态第二个练习 enums2.rs 要求变体携带真实数据。练习给出的构造表达式已经暗示了每个变体应有的形态#[derive(Debug)] struct Point { x: u64, y: u64, } #[derive(Debug)] enum Message { // TODO: Define the different variants used below. } impl Message { fn call(self) { println!({self:?}); } } fn main() { let messages [ Message::Resize { width: 10, height: 30 }, Message::Move(Point { x: 10, y: 15 }), Message::Echo(String::from(hello world)), Message::ChangeColor(200, 255, 255), Message::Quit, ]; for message in messages { message.call(); } }info.toml 中为 enums2 配置的官方 hint 明确给出了三种变体形态的命名与示例Enum variants can be defined using three different forms: struct-, tuple- and unit-like.enum EnumUsingAllVariantForms { StructLike { named_field: bool }, TupleLike(bool), UnitLike, }对照main中的构造方式可以逐个确定每个变体的形态与字段类型变体构造方式形态应定义的类型ResizeResize { width: 10, height: 30 }结构体式struct-likeResize { width: u64, height: u64 }MoveMove(Point { x: 10, y: 15 })元组式tuple-like携带一个struct Point值Move(Point)EchoEcho(String::from(hello world))元组式携带StringEcho(String)ChangeColorChangeColor(200, 255, 255)元组式携带三个无符号字节ChangeColor(u8, u8, u8)QuitQuit单元式unit-likeQuitsolutions/08_enums/enums2.rs 中的完整定义为#[derive(Debug)] enum Message { Resize { width: u64, height: u64 }, Move(Point), Echo(String), ChangeColor(u8, u8, u8), Quit, }几个类型的取值细节值得留意width/height取u64与Point的x、y字段类型一致见练习文件中已给出的struct Point定义ChangeColor(u8, u8, u8)三个分量对应 RGB 三原色u8的取值范围 0~255 正好覆盖标准颜色通道的量程——这正是元组式变体适合表达一组同质数据的场景元组式变体的分量是匿名的只能按位置取值结构体式变体是具名字段可按名字取值。二者的取舍通常取决于字段是否有自解释的语义宽高用名字更清晰RGB 三通道用位置足矣。此外练习还展示了枚举上的方法实现impl Message { fn call(self) }接收self以引用方式访问枚举值并打印。main中通过for message in messages遍历切片借用逐个调用message.call()——这说明枚举值与结构体一样是普通类型可以放进数组、取引用、实现方法只是类型的取值空间被显式枚举了出来。运行验证时注意该练习在 info.toml 中标记为test false即rustlings run enums2只要求编译并正常执行、输出五个变体的Debug表示没有断言测试。enums3用match解构枚举驱动状态机第三个练习 enums3.rs 把枚举、方法与单元测试串起来Message的定义已给出同 enums2 解答核心任务是实现State::process把每种消息分发给对应的处理方法impl State { fn resize(mut self, width: u64, height: u64) { ... } fn move_position(mut self, point: Point) { ... } fn echo(mut self, s: String) { ... } fn change_color(mut self, red: u8, green: u8, blue: u8) { ... } fn quit(mut self) { ... } fn process(mut self, message: Message) { // TODO: Create a match expression to process the different message // variants using the methods defined above. } }官方 hintinfo.toml分两步给出指引先定义枚举使其通过编译再在process()中创建match表达式并特别提醒需要在 match 表达式中解构deconstruct某些消息变体以取出其值。solutions/08_enums/enums3.rs 中process的实现即本章模式匹配主题的落点fn process(mut self, message: Message) { match message { Message::Resize { width, height } self.resize(width, height), Message::Move(point) self.move_position(point), Message::Echo(string) self.echo(string), Message::ChangeColor(red, green, blue) self.change_color(red, green, blue), Message::Quit self.quit(), } }这段代码体现了模式匹配解构变体的三种写法结构体式变体Message::Resize { width, height }按字段名解构width、height直接成为匹配臂里的绑定变量元组式变体Message::ChangeColor(red, green, blue)按位置解构三个u8分量Message::Move(point)则是整体绑定Point值单元式变体Message::Quit无需绑定直接映射到self.quit()。更关键的是 Rust 的穷尽性检查match必须覆盖Message的全部五个变体遗漏任何一个例如忘了Quit都会产生编译错误而非静默忽略。从 solutions/08_enums/enums3.rs 与 exercises/08_enums/enums3.rs 的对照可见两者除process的实现和一处注释外完全一致——这正是 rustlings 的练习机制练习文件删除关键代码段解答文件补全后作为验收基准。练习文件末尾的#[cfg(test)]测试模块则是穷尽性的直接验证器#[test] fn test_match_message_call() { let mut state State { width: 0, height: 0, position: Point { x: 0, y: 0 }, message: String::from(hello world), color: (0, 0, 0), quit: false, }; state.process(Message::Resize { width: 10, height: 30 }); state.process(Message::Move(Point { x: 10, y: 15 })); state.process(Message::Echo(String::from(Hello world!))); state.process(Message::ChangeColor(255, 0, 255)); state.process(Message::Quit); assert_eq!(state.width, 10); assert_eq!(state.height, 30); assert_eq!(state.position.x, 10); assert_eq!(state.position.y, 15); assert_eq!(state.message, Hello world!); assert_eq!(state.color, (255, 0, 255)); assert!(state.quit); }测试依次向State投递五种消息再逐一断言各字段是否按预期更新——width/height变为 10/30、位置变为 (10, 15)、消息字符串被替换、颜色变为 (255, 0, 255)、quit置为true。由于该练习在 info.toml 中没有test false标记rustlings run enums3会以cargo test方式执行此测试全部断言通过才判定完成——这与 enums1/enums2 的编译 运行验收标准不同。从源码结构看这套练习/解答双轨机制由 dev/Cargo.toml 中的 target 清单驱动每个练习注册为一对 target如enums1与enums1_sol分别指向../exercises/08_enums/enums1.rs与../solutions/08_enums/enums1.rs配合 rustlings-macros/info.toml 中的name、dir、test、hint元数据由rustlings的run/hint/check-all子命令定义于 src/cli.rs统一调度。想批量核验本章进度可以执行rustlings check-all查看各练习的 done/pending 状态。小结本章练习的知识递进练习核心知识点验收方式enums1单元变体、#[derive(Debug)]与{:?}打印编译并运行test falseenums2结构体式 / 元组式 / 单元式三种变体形态、携带数据的变体、枚举上的impl方法编译并运行test falseenums3match穷尽匹配与变体解构、以枚举消息驱动状态更新编译 cargo test断言这一章的完整学习闭环是先理解Rust 枚举 代数数据类型这一定位再依次掌握变体能携带什么数据三种形态与如何把数据取出来模式匹配解构最后依靠编译器的穷尽性检查与单元测试test_match_message_call双重保证分发逻辑没有遗漏。完成 exercises/08_enums 全部三个练习后读者即可具备编写消息驱动状态机这类典型 Rust 模式的基础这也是后续 20_threads 等章节中多线程消息传递的常见写法。【免费下载链接】rustlings:crab: Small exercises to get you used to reading and writing Rust code!项目地址: https://gitcode.com/gh_mirrors/ru/rustlings创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Windows 11 界面如何还原成自己习惯的样子:ExplorerPatcher 任务栏与开始菜单定制完整指南

Windows 11 界面如何还原成自己习惯的样子:ExplorerPatcher 任务栏与开始菜单定制完整指南

Windows 11 界面如何还原成自己习惯的样子:ExplorerPatcher 任务栏与开始菜单定制完整指南 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatch…

2026/11/12 11:47:45 阅读更多 →
3条命令跑通FBT固件编译:环境搭建到烧录的完整路径

3条命令跑通FBT固件编译:环境搭建到烧录的完整路径

3条命令跑通FBT固件编译:环境搭建到烧录的完整路径 【免费下载链接】awesome-flipperzero 🐬 A collection of awesome resources for the Flipper Zero device. 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-flipperzero 走完本文…

2026/10/25 9:47:56 阅读更多 →
Roo Code 离线模式快速上手指南:Ollama 本地模型 + 断网编程 5 分钟配齐

Roo Code 离线模式快速上手指南:Ollama 本地模型 + 断网编程 5 分钟配齐

Roo Code 离线模式快速上手指南:Ollama 本地模型 断网编程 5 分钟配齐 【免费下载链接】Roo-Code Roo Code gives you a whole dev team of AI agents in your code editor. 项目地址: https://gitcode.com/GitHub_Trending/ro/Roo-Code 高铁过隧道、酒店 W…

2026/11/11 9:01:07 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/12 5:00:00 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/12 5:13:20 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/12 5:13:20 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/11 17:16:37 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/11 17:16:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/12 5:13:20 阅读更多 →

日新闻

周新闻

月新闻