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 …...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
