【Rust练习】16.模式

文章题目来自:https://practice-zh.course.rs/pattern-match/patterns.html

1 🌟🌟 使用 | 可以匹配多个值, 而使用 …= 可以匹配一个闭区间的数值序列


fn main() {}
fn match_number(n: i32) {match n {// 匹配一个单独的值1 => println!("One!"),// 使用 `|` 填空,不要使用 `..` 或 `..=`__ => println!("match 2 -> 5"),// 匹配一个闭区间的数值序列6..=10 => {println!("match 6 -> 10")},_ => {println!("match 11 -> +infinite")}}
}

将前面学到的模式匹配进行集合就可以了

fn match_number(n: i32) {match n {// 匹配一个单独的值1 => println!("One!"),// 使用 `|` 填空,不要使用 `..` 或 `..=`2 | 3 | 4 | 5 => println!("match 2 -> 5"),// 匹配一个闭区间的数值序列6..=10 => {println!("match 6 -> 10")}others => {println!("match 11 -> +infinite")}}
}

2 🌟🌟🌟 @ 操作符可以让我们将一个与模式相匹配的值绑定到新的变量上


struct Point {x: i32,y: i32,
}fn main() {// 填空,让 p 匹配第二个分支let p = Point { x: __, y: __ };match p {Point { x, y: 0 } => println!("On the x axis at {}", x),// 第二个分支Point { x: 0..=5, y: y@ (10 | 20 | 30) } => println!("On the y axis at {}", y),Point { x, y } => println!("On neither axis: ({}, {})", x, y),}
}

这里的语法可能会让有些人非常疑惑:明明xy就在这里,为什么我要再给y绑定一个变量?如果你直接编译上述代码(我指的是修改了p的赋值之后),你会遇到如下错误:
错误
y改成p.y就可以了。

我们先考虑另外一个场景:

fn age() -> u32 {15
}fn main() {println!("Tell me what type of person you are");match age() {0 => println!("I haven't celebrated my first birthday yet"),1..=12 => println!("I'm a child of age 1..12"),13..=19 => println!("I'm a teen of age 13..19"),_ => println!("I'm an old person of age others"),}
}

一个典型的根据年龄匹配打印的函数,那如果我希望将被匹配的值,也就是age()的返回值打印出来呢?这就不太好办了。也许可以在println!里再调用一次?你知道可以这么做只是因为这里age()返回的值是固定的,如果它每次返回的值都不一样,显然不能这么做。

这时,@绑定就派上用场了。

fn main() {println!("Tell me what type of person you are");match age() {0 => println!("I haven't celebrated my first birthday yet"),n @ 1..=12 => println!("I'm a child of age {:?}", n),n @ 13..=19 => println!("I'm a teen of age {:?}", n),n => println!("I'm an old person of age {:?}", n),}
}

我们将被匹配的值绑定到n上,后续代码逻辑就可以使用了。

再考虑上面的例子,归根结底,每次匹配都只是将外部的变量和范围进行匹配,中间没有产生任何额外的变量。所以如果你想使用,要么使用原始的外部变量,要么进行一个@绑定。而匹配所有值,本质上不是匹配,就是进行了一次绑定,所以绑定的值可以直接使用

3


// 修复错误
enum Message {Hello { id: i32 },
}fn main() {let msg = Message::Hello { id: 5 };match msg {Message::Hello {id:  3..=7,} => println!("id 值的范围在 [3, 7] 之间: {}", id),Message::Hello { id: newid@10 | 11 | 12 } => {println!("id 值的范围在 [10, 12] 之间: {}", newid)}Message::Hello { id } => println!("Found some other id: {}", id),}
}

第一个需要用@绑定,第二个需要全部匹配(落个括号)

// 修复错误
enum Message {Hello { id: i32 },
}fn main() {let msg = Message::Hello { id: 5 };match msg {Message::Hello {id:id@  3..=7,} => println!("id 值的范围在 [3, 7] 之间: {}", id),Message::Hello { id: newid@(10 | 11 | 12) } => {println!("id 值的范围在 [10, 12] 之间: {}", newid)}Message::Hello { id } => println!("Found some other id: {}", id),}
}

4 🌟🌟 匹配守卫(match guard)是一个位于 match 分支模式之后的额外 if 条件,它能为分支模式提供更进一步的匹配条件。


// 填空让代码工作,必须使用 `split`
fn main() {let num = Some(4);let split = 5;match num {Some(x) __ => assert!(x < split),Some(x) => assert!(x >= split),None => (),}
}

事实上就是多一个if条件,来进一步匹配而已。

fn main() {let num = Some(4);let split = 5;match num {Some(x) if x < split => assert!(x < split),Some(x) => assert!(x >= split),None => (),}
}

5 🌟🌟🌟 使用 … 忽略一部分值


// 填空,让代码工作
fn main() {let numbers = (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048);match numbers {__ => {assert_eq!(first, 2);assert_eq!(last, 2048);}}
}

可惜只能忽略一次

fn main() {let numbers = (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048);match numbers {(first, .., last) => {assert_eq!(first, 2);assert_eq!(last, 2048);}}
}

6 🌟🌟 使用模式 &mut V 去匹配一个可变引用时,你需要格外小心,因为匹配出来的 V 是一个值,而不是可变引用


// 修复错误,尽量少地修改代码
// 不要移除任何代码行
fn main() {let mut v = String::from("hello,");let r = &mut v;match r {&mut value => value.push_str(" world!") }
}

思来想去,也只有这一种改法了。

fn main() {let mut v = String::from("hello,");let r = &mut v;match r {value => value.push_str(" world!") }
}

r本身就是对string的可变引用,如果想直接使用的话,没必要再引用一次。按图中的匹配,最后value会是一个不可变string,这样后面的操作就做不到了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

16. C++ TinyWebServer项目总结(16. 服务器调制、调试和测试)

主要包括&#xff1a; 使用 tcpdump 抓包&#xff1b;使用 gdb 调试器&#xff1b;使用压力测试工具&#xff0c;模拟现实世界中的高并发请求&#xff0c;测试服务器在高压状态下的稳定性。 最大文件描述符数 Linux 对应用进程能打开的最大文件描述符数量有两个层次的限制&a…

4. 数据结构: 对象和数组

数字、布尔值和字符串是构建数据结构的原子。不过&#xff0c;许多类型的信息需要不止一个原子。对象允许我们对值&#xff08;包括其他对象&#xff09;进行分组&#xff0c;从而构建更复杂的结构。到目前为止&#xff0c;我们所构建的程序都受到限制&#xff0c;因为它们只能…

软件设计模式——工厂模式

软件设计模式——工厂模式 文章目录 软件设计模式——工厂模式一、设计模式的认知1.1 什么是软件设计模式&#xff1a;1.2 为什么要学习设计模式&#xff1a;1.3 设计模式的分类&#xff1a; 二、工厂模式2.1 工厂模式实例&#xff1a; 一、设计模式的认知 1.1 什么是软件设计…

WordPress LearnPress插件 SQL注入复现(CVE-2024-8522)

0x01 产品描述&#xff1a; LearnPress 是一款功能强大的 WordPress LMS&#xff08;学习管理系统&#xff09;插件&#xff0c;适用于创建和销售在线课程。凭借其直观的界面和丰富的功能&#xff0c;无论您是否具备编程背景&#xff0c;都能轻松搭建起在线教育网站。学会如何使…

Java之路--瓦解逻辑控制与方法使用已是瓮中捉鳖

嗨嗨大家&#xff01;今天我们来学习逻辑运算和方法的使用~ 目录 一 逻辑控制 1 分支结构 1.1 if语句 1.2 switch 语句 2 循环结构 2.1 while 循环 2.2 for 循环 2.3 do while 循环 2.4 break 2.5 continue 3. 输出输入 二、方法的使用 1 方法定义语法 2 实参和…

网络通信——DHCP

目录 一.DHCP应用场景 二.通信过程 三.DHCP报文 四.DHCP通信原理 &#xff08;1&#xff09;租借过程 &#xff08;2&#xff09;DHCP 租期更新 &#xff08;3&#xff09;DHCP重绑定 五.一般路由器的DHCP支持两种地址池 &#xff08;1&#xff09;接口地址池 &…

进制转换,原码反码补码

正数的三码合一 1个byte8位&#xff0c;-128符号位溢出了&#xff0c;所以是1000 0000

基于Python大数据的B站热门视频的数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

全连接神经网络

这里写目录标题 全连接神经网络vs前馈神经网络基于全连接神经网络的手写数字识别使用Pytorch实现纯Python实现 全连接神经网络的局限 端到端学习 深度学习有时也称为端到端机器学习&#xff08;end-to-end machine learning&#xff09;。这里所说的端到端是指从一端到另一端的…

David律所代理Jose Martin幽默水果版权首发维权,尚未TRO

案件基本情况&#xff1a;起诉时间&#xff1a;2024/9/18案件号&#xff1a;2024-cv-08484原告&#xff1a;Jose Martin原告律所&#xff1a;David起诉地&#xff1a;伊利诺伊州北部法院涉案商标/版权&#xff1a;原告品牌简介&#xff1a;西班牙的卓越艺术家Jose Martin以他非…

网络原理之IP协议(网络层)

目录 前言 什么是IP协议&#xff1f; IP协议的协议头格式 16位总长度&#xff08;字节数&#xff09; 16位标识、3位标志位和13位片偏移 8位生存时间 IP地址管理 1.动态分配IP 2.NAT机制&#xff08;网络地址转换&#xff09; NAT机制是如何工作的 NAT机制的优缺点…

Nginx反向代理配置支持websocket

一、官方文档 WebSocket proxying 为了将客户端和服务器之间的连接从HTTP/1.1转换为WebSocket&#xff0c;使用了HTTP/1.1中可用的协议切换机制&#xff08;RFC 2616: Hypertext Transfer Protocol – HTTP/1.1&#xff09;。 然而&#xff0c;这里有一个微妙之处:由于“升级”…

论文阅读:A Generalization of Transformer Networks to Graphs

论文阅读&#xff1a;A Generalization of Transformer Networks to Graphs 论文地址1 摘要2 贡献Graph TransformerOn Graph Sparsity&#xff08;图稀疏&#xff09;On Positional Encodings&#xff08;位置编码&#xff09;3 Graph Transformer Architecture&#xff08;架…

C++:日期类的实现

目录 一、前言 二、头文件 三、各个函数的实现 打印、检查日期及获取日期 、、-、-、 、<、<、>、>、 &#xff01; 日期-日期 >>、<< 一、前言 前面几篇讲了关于类和对象的一些知识&#xff0c;本篇就来实现一下前面用到的日期类。 二、头文…

市面第一款 C++ 版本的U盘装机软件(即将上线)

市面大部分U盘装机软件&#xff0c;都是采用Au3脚本开发&#xff0c;而且有各种捆绑&#xff0c;闲来无聊&#xff0c;采用Qt C制作一款CU盘装机软件&#xff0c;从此告别Au3脚本&#xff0c;各种炫酷界面随便换&#xff0c;敬请期待 另外两个界面暂时不公布&#xff0c;防止Au…

uni-app页面调用接口和路由(四)

文章目录 一、路由二、页面调用接口二、路由跳转1.uni.navigateTo(OBJECT)2.uni.redirectTo(OBJECT)3.uni.reLaunch(OBJECT)4.uni.switchTab(OBJECT)5.uni.navigateBack(OBJECT) 总结 一、路由 路由配置 uni-app页面路由为框架统一管理&#xff0c;开发者需要在pages.json里配…

Linux —— Socket编程(一)

一、本篇重点 1. 认识IP地址、端口号、网络字节序等网络编程中的基本概念 2. 学习Socket api的基本用法 3. 能够实现一个简单的udp客户端/服务器 二、基本概念 1. 理解源IP地址和目的IP地址 简单的理解&#xff0c;IP地址是用于标识一台机器的&#xff0c;我们通过IP地址去…

Springboot常见问题(bean找不到)

如图错误显示userMapper bean没有找到。 解决方案&#xff1a; mapper包位置有问题&#xff1a;因为SpringBoot默认的包扫描机制会扫描启动类所在的包同级文件和子包下的文件。注解问题&#xff1a; 比如没有加mapper注解 然而无论是UserMapper所在的包位置还是Mapper注解都是…

大数据Hologres(一):Hologres 简单介绍

文章目录 Hologres 简单介绍 一、什么是实时数仓 Hologres 二、产品优势 1、专注实时场景 2、亚秒级交互式分析 3、统一数据服务出口 4、开放生态 5、MaxCompute查询加速 6、计算存储分离架构 三、应用场景 搭建实时数仓 四、产品架构 1、Shared Disk/Storage &am…

ER 图 Entity-Relationship (ER) diagram 101 电子商城 数据库设计

起因&#xff0c; 目的: 客户需求, 就是要设计一个数据库。 过程&#xff0c; 关于工具: UI 设计&#xff0c;我最喜欢的工具其实是 Canva, 但是 Canva 没有合适的模板。我用的是 draw.io, 使用感受是&#xff0c;很垃圾。 各种快捷键不适应&#xff0c;箭头就是点不住&…