当前位置: 首页 > news >正文

【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching)

系列文章目录

【跟小嘉学 Rust 编程】一、Rust 编程基础
【跟小嘉学 Rust 编程】二、Rust 包管理工具使用
【跟小嘉学 Rust 编程】三、Rust 的基本程序概念
【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念
【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据
【跟小嘉学 Rust 编程】六、枚举和模式匹配
【跟小嘉学 Rust 编程】七、使用包(Packages)、单元包(Crates)和模块(Module)来管理项目
【跟小嘉学 Rust 编程】八、常见的集合
【跟小嘉学 Rust 编程】九、错误处理(Error Handling)
【跟小嘉学 Rust 编程】十一、编写自动化测试
【跟小嘉学 Rust 编程】十二、构建一个命令行程序
【跟小嘉学 Rust 编程】十三、函数式语言特性:迭代器和闭包
【跟小嘉学 Rust 编程】十四、关于 Cargo 和 Crates.io
【跟小嘉学 Rust 编程】十五、智能指针(Smart Point)
【跟小嘉学 Rust 编程】十六、无畏并发(Fearless Concurrency)
【跟小嘉学 Rust 编程】十七、面向对象语言特性
【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching)

文章目录

  • 系列文章目录
    • @[TOC](文章目录)
  • 前言
  • 一、 使用到模式的地方
    • 1.1、match 分支
    • 1.2、if let 条件表达式
    • 1.3、while let 条件循环
    • 1.4、for 循环
    • 1.5、let 语句
    • 1.6、函数参数
  • 二、可辩驳性(Refutability)
    • 2.1、模式的两种形式
  • 三、模式匹配语法(Pattern Syntax)
    • 3.1、模式匹配字面值(Matching Literals)
    • 3.2、匹配命名变量
    • 3.3、多种模式
    • 3.4、匹配范围
    • 3.5、解构分解值
      • 3.5.1、解构结构
      • 3.5.2、灵活匹配
      • 3.5.3、解构枚举
      • 3.5.3、嵌套枚举和结构
      • 3.5.4、解构结构和元组
    • 3.6、模式中忽略值
      • 3.6.1、忽略某个值
      • 3.6.2、忽略值的某一部分
      • 3.6.3、忽略未使用变量警告
      • 3.6.4、使用.. 忽略值的剩余部分
      • 3.6.5、match 守卫
      • 3.6.6、@ 绑定
  • 总结

前言

模式是Rust的一种特殊语法,用于匹配复杂的和简单类型的结构,模式与匹配表达式和其他构造结合使用,可以更好的控制流。

模式由下列元素或组合组成

  • 字面值
  • 解构的数组、enum、struct、tuple
  • 变量
  • 通配符
  • 占位符

想要使用模式,需要将其与某个值进行比较,如果模式匹配,就可以在代码中使用这个值的想应部分。

主要教材参考 《The Rust Programming Language》


一、 使用到模式的地方

1.1、match 分支

match VALUE {PATTERN => EXPRESSION,PATTERN => EXPRESSION,PATTERN => EXPRESSION,
}

要求分支能够详尽所有可能性

特殊的模式: _,匹配任何值,不会绑定到变量,通常用于match的最后一个分支,用于忽略某些值。

1.2、if let 条件表达式

if let 表达式主要是作为简短的方式来替代只有一个匹配项的match,if let 可选的可以拥有 else(else if 和 else 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, {color}, as the background");} 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");}
}

1.3、while let 条件循环

只要模式继续匹配就允许循环执行。

    let mut stack = Vec::new();stack.push(1);stack.push(2);stack.push(3);while let Some(top) = stack.pop() {println!("{}", top);}

1.4、for 循环

    let v = vec!['a', 'b', 'c'];for (index, value) in v.iter().enumerate() {println!("{} is at index {}", value, index);}

1.5、let 语句

let PATTERN = EXPRESSION;
let (x, y, z) = (1, 2, 3);

1.6、函数参数

fn foo(x: i32) {// code goes here
}fn print_coordinates(&(x, y): &(i32, i32)) {println!("Current location: ({}, {})", x, y);
}fn main() {let point = (3, 5);print_coordinates(&point);
}

二、可辩驳性(Refutability)

可辩驳性:模式是否会无法匹配。

2.1、模式的两种形式

  • 模式有两种形式:可辩驳的,无可辩驳的
  • 能够匹配任何可能传递的值的模式:无可辩驳的
  • 对于某些可能的值,无法进行匹配的模式:可辩驳的
  • 函数参数、let 语句、for 循环只接受无可辩驳的模式
  • if let 和while let 接受可辩驳的和无可辩驳的模式

三、模式匹配语法(Pattern Syntax)

3.1、模式匹配字面值(Matching Literals)

    let x = 1;match x {1 => println!("one"),2 => println!("two"),3 => println!("three"),_ => println!("anything"),}

3.2、匹配命名变量

    let x = Some(5);let y = 10;match x {Some(50) => println!("Got 50"),Some(y) => println!("Matched, y = {y}"),_ => println!("Default case, x = {:?}", x),}println!("at the end: x = {:?}, y = {y}", x);

3.3、多种模式

    let x = 1;match x {1 | 2 => println!("one or two"),3 => println!("three"),_ => println!("anything"),}

3.4、匹配范围

示例:匹配数值范围

    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"),}

3.5、解构分解值

3.5.1、解构结构

示例:

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);let Point { x, y } = p;assert_eq!(0, x);assert_eq!(7, y);
}

3.5.2、灵活匹配

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})");}}
}

3.5.3、解构枚举

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 {x} and in the y direction {y}");}Message::Write(text) => {println!("Text message: {text}");}Message::ChangeColor(r, g, b) => {println!("Change the color to red {r}, green {g}, and blue {b}",)}}
}

3.5.3、嵌套枚举和结构

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 color to red {r}, green {g}, and blue {b}");}Message::ChangeColor(Color::Hsv(h, s, v)) => {println!("Change color to hue {h}, saturation {s}, value {v}")}_ => (),}
}

3.5.4、解构结构和元组

let ((feet, inches), Point { x, y }) = ((3, 10), Point { x: 3, y: -10 });

3.6、模式中忽略值

3.6.1、忽略某个值

fn foo(_: i32, y: i32) {println!("This code only uses the y parameter: {}", y);
}fn main() {foo(3, 4);
}

3.6.2、忽略值的某一部分

范例1:

    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);

范例2:

    let numbers = (2, 4, 8, 16, 32);match numbers {(first, _, third, _, fifth) => {println!("Some numbers: {first}, {third}, {fifth}")}}

3.6.3、忽略未使用变量警告

fn main() {let _x = 5;let y = 10;let s = Some(String::from("Hello!"));if let Some(_) = s {println!("found a string");}println!("{:?}", s);
}

3.6.4、使用… 忽略值的剩余部分

    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),}let numbers = (2, 4, 8, 16, 32);match numbers {(first, .., last) => {println!("Some numbers: {first}, {last}");}}

3.6.5、match 守卫

match 守卫是 match 分支模式后额外的 if 条件,想要匹配该条件也必须满足

    let num = Some(4);match num {Some(x) if x % 2 == 0 => println!("The number {} is even", x),Some(x) => println!("The number {} is odd", x),None => (),}

3.6.6、@ 绑定

    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 编程】十八、模式匹配(Patterns and Matching)

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...

keepalived+lvs+nginx高并发集群

keepalivedlvsnginx高并发集群 简介&#xff1a; keepalivedlvsnginx高并发集群&#xff0c;是通过LVS将请求流量均匀分发给nginx集群&#xff0c;而当单机nginx出现状态异常或宕机时&#xff0c;keepalived会主动切换并将不健康nginx下线&#xff0c;维持集群稳定高可用 1.L…...

剑指Offer65.不用加减乘除做加法 C++

1、题目描述 写一个函数&#xff0c;求两个整数之和&#xff0c;要求在函数体内不得使用 “”、“-”、“*”、“/” 四则运算符号。 示例: 输入: a 1, b 1 输出: 2 2、VS2019上运行 使用位运算的方法 #include <iostream>class Solution { public:/*** 计算两个整…...

【linux命令讲解大全】004.探索Linux命令行中的chmod和chown工具

文章目录 chmod概要主要用途参数选项返回值例子 chown补充说明语法选项参数实例 从零学 python chmod 用来变更文件或目录的权限 概要 chmod [OPTION]... MODE[,MODE]... FILE... chmod [OPTION]... OCTAL-MODE FILE... chmod [OPTION]... --referenceRFILE FILE...主要用途…...

nginx会话保持

ip_hash:通过IP保持会话 作用&#xff1a; nginx通过后端服务器地址将请求定向的转发到服务器上。 将客户端的IP地址通过哈希算法加密成一个数值 如果后端有多个服务器&#xff0c;第一次请求到服务器A&#xff0c; 并在务器登录成功&#xff0c;那么再登录B服务器就要重新…...

SpringBoot使用Druid连接池 + 配置监控页面(自定义版 + starter版)

目录 1. Druid连接池的功能2. 自定义版2.1 pom.xml添加依赖2.2 MyDataSourceConfig实现2.3 application.properties配置编写Controller进行测试2.4 druid监控页面查看 3. starter版3.1 pom.xml添加依赖3.2 自动配置分析3.3 使用application.properties对druid进行配置3.4 druid…...

【业务功能篇77】微服务-OSS对象存储-上传下载图片

3. 图片管理 文件存储的几种方式 单体架构可以直接把图片存储在服务器中 但是在分布式环境下面直接存储在WEB服务器中的方式就不可取了&#xff0c;这时我们需要搭建独立的文件存储服务器。 3.1 开通阿里云服务 针对本系统中的相关的文件&#xff0c;图片&#xff0c;文本等…...

【CSS 常用加载动画效果】

常用加载效果 呼吸灯效果波浪光效果转圈加载 呼吸灯效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><div id"ti"></div></body><style>b…...

python 模块requests 发送 HTTP 请求

一、简介 requests 模块是 python 基于 urllib&#xff0c;采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便&#xff0c;可以节约我们大量的工作 二、安装 pip install requestsimport requests三、方法 requsts.requst(method, url,headers,cookies,prox…...

关于 Camera 预览和录像画质不一样的问题分析

1、问题背景 基于之前安卓平台的一个项目&#xff0c;客户有反馈过一个 Camera app 预览的效果&#xff0c;和录像效果不一致的问题。 这里的预览是指打开 Camera app 后直接出图的效果&#xff1b;录像的效果则是指打开 Camera app 开启录像功能&#xff0c;录制一段视频&…...

【音视频】 视频的播放和暂停,当播放到末尾时触发 ended 事件,循环播放,播放速度

video 也可以 播放 MP3 音频&#xff0c;当不想让 视频显示出来的话&#xff0c;可以 给 video 设置宽和高 1rpx &#xff0c;不可以隐藏 <template><view class"form2box"><u-navbar leftClick"leftClick"><view slot"left&q…...

Python数据分析高薪实战第一天 python基础与项目环境搭建

开篇词 数据赋能未来&#xff0c;Python 势不可挡 互联网公司从红利下的爆发期&#xff0c;进入新的精细化发展阶段&#xff0c;亟须深入分析与挖掘业务与数据价值&#xff0c;从而找到新的增长点突破现有增长瓶颈。各行各业的数据分析需求井喷&#xff0c;数据分析人才成为争…...

pandas数据分析——groupby得到分组后的数据

groupbyagg分组聚合对数据字段进行合并拼接 Pandas怎样实现groupby聚合后字符串列的合并&#xff08;四十&#xff09; groupby得到分组后的数据 pandas—groupby如何得到分组里的数据 date_range补齐缺失日期 在处理时间序列的数据中&#xff0c;有时候会遇到有些日期的数…...

Android studio 软件git使用

在 test 分支添加的方法 , 现在切换到 master分支 总共 2 个分支 , 当前的分支是 test 出现了 先试一下 force checkout , 尝试之后发现 , 你更改没有带过来 , 以为哪个类在master分支没有 , 所以这边也没有 , 切回分支 test 发现之前的跟改没有 , 这样即可以找回 继续切换…...

通过C实现sqlite3操作,导入电子词典

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlite3.h> int main(int argc, const char *argv[]) {//创建并打开一个数据库sqlite3 *db NULL;if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){printf("…...

K8S集群中使用JDOS KMS服务对敏感数据安全加密 | 京东云技术团队

基本概念 KMS&#xff0c;Key Management Service&#xff0c;即密钥管理服务&#xff0c;在K8S集群中&#xff0c;以驱动和插件的形式启用对Secret&#xff0c;Configmap进行加密。以保护敏感数据&#xff0c; 驱动和插件需要使用者按照需求进行定制和实现自己的KMS插件&…...

SpringBoot+quartz实现定时任务的创建、删除、查询操作

1、在pom.xml文件中导入quartz的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency> 2、配置quartz的数据源等操作 package com.train.batch.config;imp…...

Oracle的学习心得和知识总结(二十八)|Oracle数据库数据库回放功能之论文二翻译及学习

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…...

排序算法:归并排序

约翰冯诺伊曼在 1945 年提出了归并排序。在讲解归并排序之前&#xff0c;我们先一起思考一个问题&#xff1a;如何将两个有序的列表合并成一个有序的列表&#xff1f; 将两个有序的列表合并成一个有序的列表 这太简单了&#xff0c;笔者首先想到的思路就是&#xff0c;将两个列…...

Hbase-技术文档-spring-boot整合使用hbase--简单操作增删改查--提供封装高可用的模版类

使用spring-boot项目来整合使用hbase。 引入依赖 <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.4.3</version> </dependency> 依赖声明表示将把Apache HBase客户端库…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

MCP和Function Calling

MCP MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09; &#xff0c;2024年11月底&#xff0c;由 Anthropic 推出的一种开放标准&#xff0c;旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...