【Rust】枚举与模式匹配

embedded/2025/1/16 12:34:12/

目录

思维导图

一、概述

1. 枚举的定义与使用

2. 特殊枚举:Option

4. 模式匹配

5. if let构造

二、枚举

1. 枚举的定义与作用

2. IP地址的枚举示例

示例代码

3. 结构体与枚举的组合

示例代码

4. 枚举变体的灵活性

示例代码

5. 枚举的方法

代码示例:

6. Option枚举的优势

标准库定义如下:

三、match模式匹配

1. match控制流构造概述

2. match表达式的工作原理

示例代码

3. match的组成部分

4. 绑定值的模式

示例代码

5. 处理Option类型

示例代码

6. match的穷尽性

示例代码(错误)

7. 捕获所有模式和_占位符

示例代码

四、if let语法

1. 控制流的简化:if let语法

示例代码

2. match与if let的比较

3. 使用else与if let

示例代码


思维导图

一、概述

1. 枚举的定义与使用

  • 枚举的概念:枚举是一种数据类型,它通过列举可能的变体来定义类型。
  • 实际应用:通过实例展示如何定义和使用枚举,以便在代码中清晰表达不同的状态或选项。

2. 特殊枚举:Option

  • Option枚举:这是Rust语言中特别有用的枚举,表示一个值可以是某个具体的内容,或者是“None”。
  • 意义:这种设计使得程序员在处理可能缺失的值时,能够更安全地管理代码逻辑,避免空指针异常等问题。

4. 模式匹配

  • match表达式:通过match表达式,可以轻松地为枚举的不同值运行不同的代码块。
  • 特点:这种方式使得代码更具可读性和可维护性。

5. if let构造

  • if let的使用:除了match表达式,Rust还提供了if let构造作为处理枚举的另一种简便语法。
  • 特定:当只关心枚举的某个特定变体时,if let可以简化代码书写。

二、枚举

1. 枚举的定义与作用

  • 定义:枚举是一种数据类型,允许将一个值限制为一组可能的值。例如,可以定义一个表示形状的枚举,包含矩形(Rectangle)、圆形(Circle)和三角形(Triangle)。
  • 作用:枚举提供了一种表达特定值的方式,特别是在需要限制值的范围时,例如处理IP地址时,IP地址可以是版本4(V4)或版本6(V6),但不能同时是两者。

2. IP地址的枚举示例

  • IP地址类型:通过IP地址的例子说明了枚举的应用,定义了一个名为IpAddrKind的枚举,包含V4V6两个变体。
示例代码
rust">enum IpAddrKind {V4,V6,
}

3. 结构体与枚举的组合

  • 结构体的使用:可以使用结构体来存储IP地址及其类型,定义了一个结构体IpAddr,其中包含kindaddress字段。
示例代码
rust">fn main() {enum IpAddrKind {V4,V6,}struct IpAddr {kind: IpAddrKind,address: String,}let home = IpAddr {kind: IpAddrKind::V4,address: String::from("127.0.0.1"),};let loopback = IpAddr {kind: IpAddrKind::V6,address: String::from("::1"),};
}

4. 枚举变体的灵活性

  • 不同数据类型:枚举的每个变体可以包含不同类型和数量的数据。例如,V4可以表示四个u8值,而V6可以表示一个String
示例代码
rust">fn main() {enum IpAddr {V4(u8, u8, u8, u8),V6(String),}let home = IpAddr::V4(127, 0, 0, 1);let loopback = IpAddr::V6(String::from("::1"));
}

5. 枚举的方法

  • 定义方法:枚举可以定义方法,类似于结构体。
代码示例
rust">fn main() {enum IpArr {V4,V6,}impl IpArr {fn call(&self) {// method body would be defined here}}
}

6. Option枚举的优势

  • Option枚举Option<T>枚举,处理值可能存在或不存在的情况,避免了空值(null)带来的问题。
  • 优势:通过强类型检查,Rust编译器确保在使用值之前处理所有可能的情况,减少了空值引发的错误.
标准库定义如下
rust">enum Option<T> {None,Some(T),
}

三、match模式匹配

1. match控制流构造概述

  • Rust提供了一个强大的控制流构造match,它允许将一个值与一系列模式进行比较,并根据匹配的模式执行相应的代码。
  • match的强大之处在于模式的表达能力和编译器确保所有可能情况都被处理的特性。

2. match表达式的工作原理

  • match可以类比为一个硬币分类机,值依次通过每个模式,直到找到第一个匹配的模式。
  • 示例:定义一个Coin枚举,包含不同类型的硬币(如PennyNickelDimeQuarter),并通过match表达式返回硬币的面值(以美分为单位)。
示例代码
rust">enum Coin {Penny,Nickel,Dime,Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {match coin {Coin::Penny => 1,Coin::Nickel => 5,Coin::Dime => 10,Coin::Quarter => 25,}
}

3. match的组成部分

  • match表达式由match关键字、要匹配的值和多个分支组成。
  • 每个分支包含一个模式和对应的代码块,模式可以是字面值、变量名或通配符。

4. 绑定值的模式

  • match分支可以绑定到匹配模式中的值,允许提取枚举变体中的数据。
  • 示例:将Quarter变体改为包含UsState值,表示不同州的硬币,并在匹配时绑定州的名称。
示例代码
rust">enum UsState {Alabama,Alaska,
}
enum Coin {Penny,Nickel,Dime,Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {match coin {Coin::Penny => 1,Coin::Nickel => 5,Coin::Dime => 10,Coin::Quarter(state) => {println!("State quarter from {state:?}!");25}}
}

5. 处理Option<T>类型

  • match也可以用于处理Option<T>类型,允许对存在和不存在的值进行不同的处理。
  • 示例:定义一个plus_one函数,接受Option<i32>,如果存在值则加1,否则返回None
示例代码
rust">fn plus_one(x: Option<i32>) -> Option<i32> {match x {None => None,Some(i) => Some(i + 1),}
}

6. match的穷尽性

  • Rust要求match表达式的模式必须覆盖所有可能性,未处理的情况会导致编译错误。
  • 示例:如果只处理Some(i)而不处理None,则会引发编译错误。
示例代码(错误)
rust">fn plus_one(x: Option<i32>) -> Option<i32> {match x {Some(i) => Some(i + 1),}
}

7. 捕获所有模式和_占位符

  • 可以使用捕获所有模式来处理特定值以外的所有情况。
  • _占位符匹配任何值且不绑定到该值,适用于不需要使用的情况。
示例代码
rust">match dice_roll {3 => add_fancy_hat(),7 => remove_fancy_hat(),_ => (),
}

四、if let语法

1. 控制流的简化:if let语法

  • 概述if let语法将iflet结合,提供了一种更简洁的方式来处理匹配某一模式的值,同时忽略其他值。
示例代码
  • 说明:使用if let来处理Option类型的值,只有在值为Some时才执行相关代码。
rust">fn main() {let config_max = Some(3u8);if let Some(max) = config_max {println!("The maximum is configured to be {max}");}
}

2. matchif let的比较

  • match的使用
    • 当使用match表达式来匹配Option类型的值时,需要添加_ => ()来处理None的情况,这增加了冗余代码。
  • if let的优势
    • 通过使用if let,可以省去处理None的冗余代码,使得代码更加简洁。
    • if let语法仅在值匹配特定模式时执行代码,避免了不必要的分支。

3. 使用elseif let

  • 扩展if let的功能
    • 可以在if let后添加else,以处理与match_情况相同的逻辑。
    • 如下示例,在处理枚举类型Coin时,使用if let来识别Quarter变体并进行状态输出,同时统计非Quarter硬币的数量。
示例代码
rust">fn main() {let coin = Coin::Penny;let mut count = 0;if let Coin::Quarter(state) = coin {println!("State quarter from {state:?}!");} else {count += 1;}
}

tips:

  • 枚举定义 --> enum
  • 枚举方法 --> impl
  • 特殊枚举 --> Option<T>(含Some和None)
  • 模式匹配 --> match
  • 单一匹配 --> if let
  • 匹配扩展 --> if let ... else

http://www.ppmy.cn/embedded/154393.html

相关文章

python mysql库的三个库mysqlclient mysql-connector-python pymysql如何选择,他们之间的区别

三者的区别 1. mysqlclient 特点&#xff1a; 是一个用于Python的MySQL数据库驱动程序&#xff0c;用于与MySQL数据库进行交互。 依赖于MySQL的本地库&#xff0c;因此在安装时需要确保系统上已安装了必要的依赖项&#xff0c;如libmysqlclient-dev等。 性能较好&#xff0c…

SCDN跟高防IP相比哪个更好

在当前的互联网环境中&#xff0c;网络攻击日益频繁和复杂&#xff0c;确保业务的安全性和稳定性成为了众多企业的首要任务。SCDN&#xff08;Secure Content Delivery Network&#xff0c;安全内容分发网络&#xff09;和高防IP作为两种常见的网络安全解决方案&#xff0c;各自…

【IDEA 2024】学习笔记--文件选项卡

在我们项目的开发过程中&#xff0c;由于项目涉及的类过多&#xff0c;以至于我们会打开很多的窗口。使用IDEA默认的配置&#xff0c;个人觉得十分不便。 目录 一、设置多个文件选项卡按照文件字母顺序排列 二、设置多个文件选项卡分行显示 一、设置多个文件选项卡按照文件字…

DCU异构程序--矩阵乘

目录 一、概述 二、程序实现 三、编译运行 一、概述 HIP属于显式编程模型&#xff0c;需要在程序中明确写出并行控制语句&#xff0c;包括数据传输、核函数启动等。核函数是运行在DCU上的函数&#xff0c;在CPU端运行的部分称为主机端&#xff08;主要是执行管理和启动&…

YOLOv9改进,YOLOv9自研检测头融合HAttention用于图像修复的混合注意力检测头

参考文章 完成本篇内容,首先完成这篇文章,并把代码添加到 YOLOv9 中: YOLOv9改进,YOLOv9引入HAttention注意机制用于图像修复的混合注意力转换器,CVPR2023,超分辨率重建 下文都是手把手教程,跟着操作即可添加成功 目录 参考文章🎓一、YOLOv9原始版本代码下载🍀🍀…

npx和npm区别

npx 和 npm 是 Node.js 生态中的两个工具&#xff0c;它们有不同的用途和功能&#xff1a; 1. npm&#xff08;Node Package Manager&#xff09; 主要作用&#xff1a; 包管理工具&#xff1a; 用来安装、管理、卸载 Node.js 的包&#xff08;module/library&#xff09;。提…

PyCharm与GitHub完美对接: 详细步骤指南

在现代软件开发中,版本控制系统已经成为不可或缺的工具。GitHub作为最流行的代码托管平台,与PyCharm这款强大的Python IDE的结合,可以极大地提高开发效率。本文将为您详细介绍如何在PyCharm中无缝对接GitHub,助您轻松实现代码版本管理和团队协作。 © ivwdcwso (ID: u0…

从0开始学习搭网站第二天

前言&#xff1a;今天比较惭愧&#xff0c;中午打铲吃了一把&#xff0c;看着也到钻二了&#xff0c;干脆顺手把这个赛季的大师上了&#xff0c;于是乎一直到网上才开始工作&#xff0c;同样&#xff0c;今天的学习内容大多来自mdn社区mdn 目录 怎么把文件上传到web服务器采用S…