rust模式和匹配
文章目录
- 模式和匹配
- match 分支
- if let表达式
- while let
- for 循环
- let 语句
- 函数参数
- Refutability(可失败)与Irrefutable(不可失败的)
- 模式语法
- 匹配字面量
- 匹配命名变量
- 多个模式
- 通过 ..= 匹配值的范围
- 解构并分解值
- 解构结构体
- 使用字面量作为结构体模式的一部分进行解构
- 解构枚举
- 解构嵌套的结构体和枚举
- 解构结构体和元组
- 忽略模式中的值
- 使用 _ 忽略整个值
- 使用嵌套的 _ 忽略部分值
- 通过在名字前以一个下划线开头来忽略未使用的变量
- 用 .. 忽略剩余值
- 匹配守卫提供的额外条件
- @ 绑定
- 参考
模式和匹配
match 分支
所有结果都得匹配到
// Match Expressionfn main() {#[derive(Debug)]enum Language {English,Spanish,Russian,Japanese,}let language = Language::English;match language {Language::English => println!("Hello World!"),Language::Spanish => println!("Hola Mundo!"),Language::Russian => println!("npuBeT, Mnp!"),//_=> println!("Unsupported language!"),lang => println!("Unsupported language! {:?}", lang),}
}
if let表达式
if let表达式缺点:编译期无法强制保证覆盖所有的情况
fn main() {let favorite_color: Option<&str> = None;let is_tuesday = false;let age: Result<u8, _> = "34".parse();if let Some(color) = favorite_color {println!("Using your favorite color, {}, as the background", color);} else if is_tuesday {println!("Tuesday is green day!");} else if let Ok(age) = age {if age > 30 {println!("Using purple as the background color");} else {println!("Using orange as the background color");}} else {println!("Using blue as the background color");}
}
while let
#![allow(unused)]
fn main() {let mut stack = Vec::new();stack.push(1);stack.push(2);stack.push(3);// 一旦其返回 None,while 循环停止。while let Some(top) = stack.pop() {println!("{}", top);}
}
for 循环
#![allow(unused)]
fn main() {let v = vec!['a', 'b', 'c'];for (index, value) in v.iter().enumerate() {println!("{} is at index {}", value, index);}
}
let 语句
#![allow(unused)]
fn main() {let x = 5;// 将指分别绑定到x, y和z上let (x, y, z) = (1, 2, 3);let (x, y, _) = (1, 2, 3);
}
函数参数
//一个在参数中解构元组的函数
fn print_coordinates(&(x, y): &(i32, i32)) {println!("Current location: ({}, {})", x, y);
}fn main() {let point = (3, 5);print_coordinates(&point);
}
Refutability(可失败)与Irrefutable(不可失败的)
fn main() {// Irrefutable(不可失败的)let x = 5;// Refutable(可失败的),如果x是None,模式则无法匹配let x: Option<&str> = None;if let Some(x) = x {println!("{}", x)}// 只能接受不可失败模式//function parameters// let statements// for loops// 既可以接受可失败,也可以接受不可失败// if let// while let
}
fn main() {let x: Option<&str> = None;let Some(x) = x; //error:`let` bindings require an "irrefutable pattern"//error:这个模式总是匹配,所以这个 `if` 没啥用if let x = 5 {println!("{}", x);};
}
模式语法
匹配字面量
fn main() {let x = 1;match x {1 => println!("one"),2 => println!("two"),3 => println!("three"),_ => println!("anything"),}
}
匹配命名变量
fn main() {let x = Some(5);let y = 10;match x {Some(50) => println!("Got 50"),Some(y) => println!("Matched, y = {:?}", y),//因为定义了y,会遮蔽外面的y_ => println!("Default case, x = {:?}", x),}println!("at the end: x = {:?}, y = {:?}", x, y);
}
多个模式
#![allow(unused)]
fn main() {
let x = 1;match x {1 | 2 => println!("one or two"),3 => println!("three"),_ => println!("anything"),
}
}
通过 …= 匹配值的范围
只适用于数值和字符
#![allow(unused)]
fn main() {let x = 5;match x {1..=5 => println!("one through five"),_ => println!("something else"),}let x = 'c';match x {'a'..='j' => println!("early ASCII letter"),'k'..='z' => println!("late ASCII letter"),_ => println!("something else"),}
}
解构并分解值
解构结构体
struct Point {x: i32,y: i32,
}fn main() {let p = Point { x: 0, y: 7 };let Point { x: a, y: b } = p;assert_eq!(0, a);assert_eq!(7, b);
}
可以简写如下:
struct Point {x: i32,y: i32,
}fn main() {let p = Point { x: 0, y: 7 };let Point { x, y } = p;assert_eq!(0, x);assert_eq!(7, y);
}
使用字面量作为结构体模式的一部分进行解构
fn main() {let p = Point { x: 0, y: 7 };match p {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),}
}
解构枚举
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 => {println!("The Quit variant has no data to destructure.")}Message::Move { x, y } => {println!("Move in the x direction {} and in the y direction {}",x,y);}Message::Write(text) => println!("Text message: {}", text),Message::ChangeColor(r, g, b) => {println!("Change the color to red {}, green {}, and blue {}",r,g,b)}}
}
解构嵌套的结构体和枚举
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)) => {println!("Change the color to red {}, green {}, and blue {}", r, g, b)}Message::ChangeColor(Color::Hsv(h, s, v)) => {println!("Change the color to hue {}, saturation {}, and value {}",h, s, v)}_ => (),}
}
解构结构体和元组
#![allow(unused)]
fn main() {
struct Point {x: i32,y: i32,
}let ((feet, inches), Point {x, y}) = ((3, 10), Point { x: 3, y: -10 });
}
忽略模式中的值
使用 _ 忽略整个值
fn foo(_: i32, y: i32) {println!("This code only uses the y parameter: {}", y);
}fn main() {foo(3, 4);
}
使用嵌套的 _ 忽略部分值
#![allow(unused)]
fn main() {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;}}println!("setting is {:?}", setting_value);
}
let numbers = (2, 4, 8, 16, 32);match numbers {(first, _, third, _, fifth) => {println!("Some numbers: {}, {}, {}", first, third, fifth)},
}
通过在名字前以一个下划线开头来忽略未使用的变量
给变量增加下划线前缀和使用_是不同的
fn main() {let _x = 5;let y = 10;
}
#![allow(unused)]
fn main() {let s = Some(String::from("Hello!"));//s中的值会被移入到_s中,虽然你用了忽略if let Some(_s) = s {println!("found a string");}println!("{:?}", s);
}
解决办法
#![allow(unused)]
fn main() {let s = Some(String::from("Hello!"));// 然而只使用下划线本身,并不会绑定值。if let Some(_) = s {println!("found a string");}println!("{:?}", s);
}
用 … 忽略剩余值
#![allow(unused)]
fn main() {
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),
}
}
… 会扩展为所需要的值的数量
fn main() {let numbers = (2, 4, 8, 16, 32);match numbers {(first, .., last) => {println!("Some numbers: {}, {}", first, last);}}
}
匹配守卫提供的额外条件
#![allow(unused)]
fn main() {let num = Some(4);match num {Some(x) if x < 5 => println!("less than five: {}", x),Some(x) => println!("{}", x),None => (),}
}
fn main() {let x = Some(5);let y = 10;match x {Some(50) => println!("Got 50"),Some(n) if n == y => println!("Matched, n = {}", n),//个 y 正是 外部的 y _ => println!("Default case, x = {:?}", x),}println!("at the end: x = {:?}, y = {}", x, y);
}
#![allow(unused)]
fn main() {
let x = 4;
let y = false;match x {4 | 5 | 6 if y => println!("yes"),//且_ => println!("no"),
}
}
@ 绑定
#![allow(unused)]
fn main() {enum Message {Hello { id: i32 },}let msg = Message::Hello { id: 5 };match msg {// Message::Hello 的 id 字段是否位于 3..=7 范围内,同时也希望能将其值绑定到 id_variable 变量中以便此分支相关联的代码可以使用它。可以将 id_variable 命名为 idMessage::Hello {id: id_variable @ 3..=7,} => {println!("Found an id in range: {}", id_variable)}// 没有将 id 值保存进一个变量。Message::Hello { id: 10..=12 } => {println!("Found an id in another range")}Message::Hello { id } => {println!("Found some other id: {}", id)}}
}
参考
- 第18章~模式和匹配
相关文章:
rust模式和匹配
文章目录 模式和匹配match 分支if let表达式while letfor 循环let 语句函数参数 Refutability(可失败)与Irrefutable(不可失败的)模式语法匹配字面量匹配命名变量多个模式通过 .. 匹配值的范围 解构并分解值解构结构体使用字面量作为结构体模式的一部分进…...
Vue实际应用之无限滚动、css之、混合宏和~
目录 vue-infinite-scroll 引入工程 全局配置 按需引入 使用方式 属性说明 常见问题及解决方案 CSS中的&的用法 vue中,import 后面的波浪号~ scss中的混合宏 直接看使用 今天来点实际的,看起来简单但是给我们代码带来更好的效果&#x…...
资产安全加固的面试点
资产加固 资产管理属于蓝队前期要做的事情,首先客户单位对他自身的单位资产有一定的了解哪些资产的优先级和重要程度等等,所以开始要做相关的资产梳理,对客户单位进行统计,梳理,分析,找到哪些点是可以授权…...
鸿蒙版APP-图书购物商城案例
鸿蒙版-小麦图书APP是基于鸿蒙ArkTS-API12环境进行开发,不包含后台管理系统,只有APP端,页面图书数据是从第三方平台(聚合数据)获取进行展示的,包含登录,图书类别切换,图书列表展示,图书详情查看…...
酒店电子门牌系统的功能
在现代酒店运营中,酒店电子门牌系统正发挥着不可或缺的作用,它以一系列强大的功能重塑了酒店客房管理与住客体验。 一、客房状态显示功能 酒店电子门牌系统能够实时准确地显示客房状态。对于酒店工作人员而言,这是高效管理的得力助手。当客房…...
通义灵码生成的流程图是黑色背景怎么办
摘要:VSCODE中的通义灵码插件解释源代码的时候,可以生成mermaid流程图,但是有的时候会生成黑色背景流程图,导致连接线看不到。本文介绍一下如何去掉黑色背景,恢复正常显示。 如下图所示,这样的流程图是看不…...
云渲染:服务器机房与物理机房两者有什么区别
云渲染选择服务器机房与物理机房两者主要区别在哪里呢? 服务器机房和物理机房作为云渲染的基础设施,各自扮演着不同的角色。 服务器机房的特点 服务器机房,通常指的是那些专门用于托管服务器的设施,它们可能位于云端,…...
Docker无缝更新Zentao
在现代软件开发中,保持项目管理工具的更新对于提高团队效率至关重要。对于使用Docker部署Zentao(禅道)的团队来说,如何在不影响日常业务的情况下进行更新是一个常见挑战。本文将基于一个实际的Docker Compose配置,详细介绍如何在Docker环境中实现Zentao的无缝更新。 1. 当…...
FMEA在网络安全中的应用实践
提起FMEA,人们往往首先想到的是汽车制造、航空航天等高精密行业。它通过对产品或过程中潜在的失效模式进行识别、评估及预防,确保产品从设计到生产的每一步都尽可能减少故障发生的可能性。而在网络安全领域,FMEA同样展现出了非凡的潜力。它帮…...
【debug】QT 相关问题error汇总 QT运行闪退 QT5升级到QT6注意要点
总结一下碰到过的所有问题error以及解决方案 如果这个文档未帮助到你,仍有bug未解决,可以在下方评论留言,有偿解决。 qt的UI更新之后构建后发现没有变化 取消项目中的Shadow build的勾选,作用是取消影子构建,此后构建目…...
React Native 全新架构来了
React Native 0.76 现已在 npm 上以全新架构默认发布! 在 0.76 版本的发布博客中,我们分享了此版本包含的一系列重大更改。在本文中,我们将概述全新架构以及它如何塑造 React Native 的未来。 全新架构全面支持现代 React 功能,…...
@ConditionalOnClass编译问题
@ConditionalOnClass/@ConditionalOnMissingClass 使用场景 和@Configuration一起使用,用于条件注入 问题一 为什么我们使用的第三方jar中,指定的类型不存在,第三方jar在编译时仍然通过?还打出了jar包? 下图为spring-boot-autoconfigure中的一个配置类SecurityDataCo…...
Redis - 哨兵(Sentinel)
Redis 的主从复制模式下,⼀旦主节点由于故障不能提供服务,需要⼈⼯进⾏主从切换,同时⼤量 的客⼾端需要被通知切换到新的主节点上,对于上了⼀定规模的应⽤来说,这种⽅案是⽆法接受的, 于是Redis从2.8开始提…...
unity显示获取 年月日周几【日期】
unity显示获取 年月日周几【日期】 public void ShowDate(Text txt){//txt.text DateTime now DateTime.Now; // 获取当前时间int year now.Year; // 获取年份int month now.Month; // 获取月份(1-12)int day now.Day; // 获取天数(1-31&…...
MYSQL隔离性原理——MVCC
表的隐藏字段 表的列包含用户自定义的列和由系统自动创建的隐藏字段。我们介绍3个隐藏字段,不理解也没有关系,理解后面的undo log就懂了: DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录创建这条记…...
Android ANR分析总结
1、ANR介绍 ANR(Application Not Responding)指的是应用程序无响应,当Android应用程序在主线程上执行长时间运行的操作或阻塞I/O操作时发生。这可能导致应用程序界面冻结或无法响应用户输入。 1、Service ANR:前台20s࿰…...
Three.js 纹理贴图
1. 纹理贴图 在Three.js中,纹理贴图是一种将二维图像贴到三维物体表面的技术,以增强物体的视觉表现。纹理贴图可以使物体表面更加真实、细腻,为场景增色不少。 在Three.js中,纹理贴图的加载主要通过THREE.TextureLoader类实现。…...
2024年软件设计师中级(软考中级)详细笔记【12】软件系统分析与设计
目录 前言第12章 软件系统分析与设计12.2 数据库分析与设计12.2.1 数据库设计的策略与步骤12.2.2 需求分析12.2.3 概念结构设计12.2.4 逻辑结构设计12.2.5 数据库的物理设计 结语 前言 在备考软件设计师中级考试的过程中,我遇到了些许挑战,也收获了宝贵…...
【Windows】CMD命令学习——系统命令
CMD(命令提示符)是Windows操作系统中的一个命令行解释器,允许用户通过输入命令来执行各种系统操作。 系统命令 systeminfo - 显示计算机的详细配置信息。 tasklist - 显示当前正在运行的进程列表。 taskkill - 终止正在运行的进程。例如&am…...
React第一个项目
运行效果: 知识讲解: 组件:先定义后使用,用户界面的构成要素(标签、css和JavaScript) 定义组件: 导出组件:export default 前缀是JavaScript标准语法 定义函数:function …...
昇腾CANN opbase 算子注册与分发调度:从 API 到 AI Core 的路径追踪
所有 CANN 算子都依赖 opbase——它不是写具体算子的地方,而是算子的"注册中心 调度器"。用户调用 torch.nn.functional.softmax(x) → PyTorch 转发到 CANN → CANN 查 opbase 的算子注册表 → 找到对应的 Ascend C kernel → 加载到 AI Core → 执行。…...
机器学习势函数结合热力学积分:高效精准预测材料高温热力学性质
1. 项目概述与核心价值在材料科学和凝聚态物理领域,准确预测材料的热力学性质——如热容、热膨胀系数和体模量——是理解其相稳定性、设计新型合金和优化材料性能的基石。这些性质直接关联到材料的自由能面,而自由能面的精确计算,尤其是在高温…...
Linux内核启动时,你的isolcpus参数到底经历了什么?从GRUB到CPU掩码的完整旅程
Linux内核启动时,isolcpus参数的奇幻漂流:从GRUB配置到CPU隔离的完整解密当你在GRUB配置文件中写下isolcpus2-3这行看似简单的指令时,可能不会想到这个字符串将经历一场跨越多个软件层的奇妙旅程。本文将带你以侦探视角,追踪这个参…...
别再只懂ls -l了!手把手教你用getfattr/setfattr玩转Linux文件隐藏属性
别再只懂ls -l了!手把手教你用getfattr/setfattr玩转Linux文件隐藏属性 在Linux系统中,文件权限和属性管理是每个开发者和管理员的必修课。大多数人熟悉 ls -l 展示的基础权限,但很少有人深入探索文件系统中那些不为人知的"隐藏技能&q…...
五轴联动机床:什么叫真正做出来了,什么叫组装贴牌
机床厂的数量从来不是问题。打开任何一份机床企业名录,数以千计的厂商密密麻麻排在那里,官网上都写着"五轴联动"“高精度数控”“航空级加工”。但做五轴联动整机与自主数控系统的工厂,放到整个行业里只是极小的一部分;…...
Python爬虫实战:爬取论文期刊 文献整理+管理表生成
写论文的时候最烦什么?不是写内容,是找文献和整理文献。相信每个研究生都有过这样的经历:打开十几个浏览器标签页,一篇一篇复制论文标题、作者、期刊、发表时间、摘要,然后粘贴到Excel里,一不小心还会复制错…...
Claude Mythos:AI驱动的自动化漏洞挖掘与攻防范式跃迁
1. 项目概述:一场静默却震耳欲聋的AI能力跃迁这周,整个AI安全圈没有爆炸性新闻稿,没有铺天盖地的发布会直播,只有一份措辞克制、数据密集的系统卡片(System Card)和一份由英国AI安全研究所(AISI…...
Node.js后端服务如何集成多模型能力并管理API成本
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Node.js后端服务如何集成多模型能力并管理API成本 1. 场景与需求 在Node.js后端服务中集成AI对话功能,开发者通常面临…...
taotoken的按token计费模式如何帮助个人开发者控制实验成本
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken的按Token计费模式如何帮助个人开发者控制实验成本 对于个人开发者、学生或独立研究者而言,在探索AI应用或进行…...
纯血鸿蒙彻底告别安卓依赖:HarmonyOS 7.0 即将正式发布,国产操作系统迎来真正转折点
OpenHarmony 7.0 Beta1已经悄然上线GitCode,开发者体验官招募也同步启动。多数人还在讨论鸿蒙又更新了版本,但很少有人注意到这次更新的核心变化:纯血鸿蒙终于移除了对Android APK兼容层的依赖。这仅仅是一次常规版本迭代吗?还是国…...
