深入理解Rust的模式匹配

server/2024/11/24 0:35:32/

文章目录

    • 基础用法
    • 高级用法
      • 添加匹配守卫
      • 范围匹配
      • 切片模式
      • 变量绑定
      • 使用..进行模糊匹配
      • 使用_进行值忽略
      • 固定某个字段的匹配
      • 多分支匹配
    • 其它匹配方式
      • if let匹配方式
      • 使用matches!宏进行匹配

在Rust编程语言中,模式匹配是一种非常强大的功能,它允许开发者以灵活和表达性强的方式处理值。这是通过使用match语句和模式来实现的,它类似于其他语言中的switch语句,但提供了更多的灵活性和安全性。

基础用法

在Rust中match语句允许你将一个值与一系列模式进行比较,并根据匹配到的模式执行相应的代码块。
Rust的模式匹配支持多种不同的模式类型,包括:
1.字面值: 匹配具体的数值或者布尔值等。
2.绑定: 通过模式将值绑定到变量。
3.元组和结构体: 可以对元组或结构体的具体结构进行模式匹配
4.枚举: 匹配枚举的不同变体。
5.引用: 匹配引用,包括通过解引用进行匹配。
6.范围: 匹配一个范围内的值,例如 1…=5 表示从 1 到 5 的所有值。

匹配各种类型

Rust中match语法的调用模版如下:

rust">//语法结构
match target {模式1 => 表达式1,模式2 => {语句1;语句2;表达式2},_ => 表达式3
}

匹配字面值

rust">//匹配字面值   
let x = 3;
match x {1 => println!("one"),2 => println!("two"),3 => println!("three"),//_用与匹配其它的参数 类似于C++的default  _ => println!("anything"),
}

匹配枚举值

rust">//匹配枚举类型  
enum Direction {East,West,North,South,
}fn main() {let dire = Direction::South;match dire {Direction::East => println!("East"),//匹配North 或 South  Direction::North | Direction::South => {println!("South or North");},//匹配剩余的其它类型  //除了_通配符,用一个变量来承载其他情况也是可以的//other => println!("other direction: {:?}", other),_ => println!("West"),//_ =>() 空操作};
}

匹配结构体

rust">struct Point {x: i32,y: i32,
}let point = Point { x: 0, y: 7 };match point {Point { x, y: 0 } => println!("On the x axis at {}", x),Point { x: 0, y } => println!("On the y axis at {}", y),Point { x, y } => println!("On neither axis: ({}, {})", x, y),
}

匹配嵌套的结构体和枚举

rust">enum Color {Rgb(i32, i32, i32),Hsv(i32, i32, i32),
}
enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(Color),
}fn main() {let msg = Message::ChangeColor(Color::Hsv(0, 160, 255));match msg {Message::ChangeColor(Color::Rgb(r, g, b)) => {}Message::ChangeColor(Color::Hsv(h, s, v)) => {}_ => ()}
}

模式匹配赋值

match本身也是一个表达式,除了可以用来处理业务逻辑之外还可以用来赋值。

rust">enum IpAddr {Ipv4,Ipv6
}
fn main() {let ip1 = IpAddr::Ipv6;//模式匹配的结果赋值给ip_strlet ip_str = match ip1 {IpAddr::Ipv4 => "127.0.0.1",_ => "::1",};println!("{}", ip_str);
}

提取绑定值

模式匹配的时候提取枚举中的绑定值。

rust">//提取枚举值中绑定的数据  
enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),
}fn main() {let msg = Message::ChangeColor(0, 160, 255);match msg {Message::Quit => {}Message::Move { x, y } => {}Message::Write(text) => println!("Text message: {}", text),Message::ChangeColor(r, g, b) => {}}
}

解构Option

rust">enum Option<T> {None,Some(T),
}
fn plus_one(x: Option<i32>) -> Option<i32> {match x {None => None,Some(i) => Some(i + 1),}
}
let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);

高级用法

添加匹配守卫

match语句的模式可以包含守卫(guard),增加则外的条件判断,用于在模式匹配后进一步确定是否执行对应的代码块。

rust">let num = Some(4);
match num {//Some(x) 且x<5执行该语句  x<5就是匹配守卫 进行额外的条件判断  Some(x) if x < 5 => println!("less than five"),Some(x) => println!("greater than or equal to five"),None => (),
}

范围匹配

不用一个一个写对应的匹配值,直接匹配一定范围内的值。通过序列 …= 匹配值的范围

rust">//匹配1--5  
let x = 5;
match x {1..=5 => println!("one through five"),_ => println!("something else"),
}//匹配a--j  k--z  
let x = 'c';
match x {'a'..='j' => println!("early ASCII letter"),'k'..='z' => println!("late ASCII letter"),_ => println!("something else"),
}

切片模式

Rust的模式匹配还可以应用于数组和切片,这使得处理数据序列时更加灵活

rust">let arr = [1, 2, 3];
match arr {//匹配以1开头的数组  [1, _, _] => println!("Starts with one"),//匹配以2为中间值的数组 [_, 2, _] => println!("Contains two in the middle"),//匹配以3结尾的数组 [_, _, 3] => println!("Ends with three"),//匹配其它值  _ => println!("Does not match any pattern"),
}

变量绑定

Rust的模式匹配还支持使用@进行绑定,这允许在进行模式匹配的同时,将匹配的值绑定到变量上.

rust">//当你既想要限定分支范围,又想要使用分支的变量时,就可以用 @ 来绑定到一个新的变量上
enum Message {Hello { id: i32 },
}
let msg = Message::Hello { id: 5 };
match msg {Message::Hello { id: id_variable @ 3..=7 } => {println!("Found an id in range: {}", id_variable)},Message::Hello { id: 10..=12 } => {println!("Found an id in another range")},Message::Hello { id } => {println!("Found some other id: {}", id)},
}

使用…进行模糊匹配

rust">//用 .. 忽略剩余值
struct Point {x: i32,y: i32,z: i32,
}
let origin = Point { x: 0, y: 0, z: 0 };
match origin {//不关心后续的值 只匹配第一个值Point { x, .. } => println!("x is {}", x),
}

使用_进行值忽略

rust">//使用_忽略整个值  忽略第一个参数  只使用第二个参数 
fn foo(_: i32, y: i32) {println!("This code only uses the y parameter: {}", y);
}
fn main() {foo(3, 4);
}//使用嵌套的_忽略部分值
let mut setting_value = Some(5);
let new_setting_value = Some(10);match (setting_value, new_setting_value) {//忽略绑定值 不进行操作  (Some(_), Some(_)) => {println!("Can't overwrite an existing customized value");}_ => {setting_value = new_setting_value;}
}//忽略特定位置的值,只操作未被忽略的值  
let numbers = (2, 4, 8, 16, 32);
match numbers {(first, _, third, _, fifth) => {println!("Some numbers: {}, {}, {}", first, third, fifth)},
}//使用下划线开头表示未使用的变量
//只使用_和使用以下划线开头的名称有些微妙的不同: 比如_x仍会将值绑定到变量,而_则完全不会绑定。
fn main() {let _x = 5;let y = 10;
}

固定某个字段的匹配

rust">//固定某个字段的匹配模式
fn main() {let p = Point { x: 0, y: 7 };match p {//y=0 的匹配  Point { x, y: 0 } => println!("On the x axis at {}", x),//x=0 的匹配  Point { x: 0, y } => println!("On the y axis at {}", y),Point { x, y } => println!("On neither axis: ({}, {})", x, y),}
}

多分支匹配

增加了逻辑或操作,一个语句里面匹配多个条件

rust">//多分支匹配 
let x = 1;
match x {1 | 2 => println!("one or two"),3 => println!("three"),_ => println!("anything"),
}

其它匹配方式

if let匹配方式

当你只要匹配一个条件,且忽略其他条件时就用if let ,否则都用match

rust">let v = Some(3u8);
match v {Some(3) => println!("three"),_ => (),
}
//等价于
if let Some(3) = v {println!("three");
}

使用matches!宏进行匹配

rust">enum MyEnum {Foo,Bar
}
fn main() {let v = vec![MyEnum::Foo,MyEnum::Bar,MyEnum::Foo];//过滤Foo v.iter().filter(|x| matches!(x, MyEnum::Foo));//其它匹配方式let foo = 'f';assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));let bar = Some(4);assert!(matches!(bar, Some(x) if x > 2));
}

http://www.ppmy.cn/server/144398.html

相关文章

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点&#xff1a; STP的选举&#xff08;Listening状态中&#xff09;&#xff1a; RSTP P/A&#xff08;提议/同意&#xff09;机制 同步机制&#xff1a; 边缘端口的配置&#xff1a; RSTP的端口角色划分&#xff1a; ensp模拟…

C++设计模式行为模式———中介者模式

文章目录 一、引言二、中介者模式三、总结 一、引言 中介者模式是一种行为设计模式&#xff0c; 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。 中介者模式可以减少对象之间混乱无序的依赖关系&…

蓝桥杯模拟

【问题描述】 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。本题的结果为一个整数&#xff0c;在提交答案时只…

2022 年中高职组“网络安全”赛项-海南省省竞赛任务书-1-B模块B-1-Windows操作系统渗透测试

前言 本章节我将带领大家一起重新模拟操作一次Windows渗透测试模块&#xff0c;并加固的流程。 任务概览 环境部署 我的实验复现环境&#xff1a; 服务器Windows server 2008 R2 攻击机Kali Linux 场景操作系统Windows 7 额外还有台交换机支持&#xff1a; 这里我使用的是…

Unreal从入门到精通之如何绘制用于VR的3DUI交互的手柄射线

文章目录 前言实现方式MenuLaser实现步骤1.Laser和Cursor2.移植函数3.启动逻辑4.检测射线和UI的碰撞5.激活手柄射线6.更新手柄射线位置7.隐藏手柄射线8.添加手柄的Trigger监听完整节点如下:效果图前言 之前我写过一篇文章《Unreal5从入门到精通之如何在VR中使用3DUI》,其中讲…

web——sqliabs靶场——第十二关——(基于错误的双引号 POST 型字符型变形的注入)

判断注入类型 a OR 1 1# 发现没有报错 &#xff0c;说明单引号不是闭合类型 测试别的注入条件 a) OR 1 1# a)) OR 1 1# a" OR 11 发现可以用双引号闭合 发现是")闭合 之后的流程还是与11关一样 爆破显示位 先抓包 是post传参&#xff0c;用hackbar来传参 unam…

《Spring Cloud 微服务》

一、引言 在现代软件开发中&#xff0c;微服务架构已成为主流趋势。Spring Cloud 作为构建微服务架构的强大工具集&#xff0c;提供了一系列组件和解决方案&#xff0c;帮助开发者轻松构建、部署和管理分布式系统。本文将深入介绍 Spring Cloud 的核心概念、主要组件、工作原理…

指南: 如何在 MEV 项目中使用 Yul

这对我来说是一个反复出现的故事。我学习了一些 Solidity&#xff0c;发现了一个我想要研究的服务。代码看起来是这样的&#xff1a; Seaport Core: BasicOrderFulfiller.sol Solidity 代码在哪里&#xff1f;人们似乎不再使用普通的 Solidity 代码了 &#x1f972; 这种在智能…