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

【Rust自学】6.3. 控制流运算符-match

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

6.3.1. 什么是match

match允许一个值与一系列模式进行匹配,并执行匹配的模式对应的代码。模式可以是字面值、变量名、通配符等等。

match表达式想象为硬币分类机:硬币沿着带有不同大小孔的轨道滑下,每枚硬币都会从它遇到的第一个适合的孔落下。以同样的方式,值会遍历match中的每个模式,并且在第一个模式中值“适合”,该值落入要在执行期间使用的关联代码块中。

6.3.2. match的应用

来看个例子:编写一个函数,接受一枚未知的美国硬币,并以与计数机类似的方式确定它是哪种硬币并返回其价值(以美分为单位)。

enum Coin {Penny,// 1美分Nickel,// 5美分Dime,// 10美分Quarter,// 25美分
}fn value_in_cents(coin: Coin) -> u8 {match coin {Coin::Penny => 1,Coin::Nickel => 5,Coin::Dime => 10,Coin::Quarter => 25,}
}
  • match关键字后跟一个表达式,在本例中是值 coin 。这看起来与if中使用的条件表达式非常相似,但有一个很大的区别:if 的条件需要布尔值,但match可以是任何类型。本例中的coin类型是我们在第一行定义的Coin枚举。

  • 然后是花括号,花括号里有4个分支(英文叫arm),每个分支都是由待匹配的模式和它对应的代码来组成的。第一个分支Coin::Penny => 1,就使用Coin::Penny作为它的模式,中间的=>分隔模式和要运行的代码,这里要运行代码就是值:1,也就是返回1这个值。不同的分支之间使用,隔开。

  • match表达式执行时会把match后的表达式,在这里是coin,从上到下依次与里面的分支进行比较,如果模式与值匹配,则执行与该模式关联的代码。如果该模式与值不匹配,则继续执行下一个分支。匹配成功的分支所对应的代码表达式会作为整个match表达式的值进行返回。
    比如说match匹配到5美分,也就是Coin::Nickel上了,那么整个表达式的值就是5。又因为match表达式是value_in_cents这个函数中的最后一个表达式,所以它的值,也就是5,会作为函数的返回值。

  • 这里因为每个分支对应的代码都很简单,所以用=>就可以了,但如果一个分支对应的是多行代码,就需要用花括号把多行代码括起来。如下例:

fn value_in_cents(coin: Coin) -> u8 {match coin {Coin::Penny => {println!("Lucky penny!");1}Coin::Nickel => 5,Coin::Dime => 10,Coin::Quarter => 25,}
}

6.3.3. 绑定值的模式

匹配的分支可以绑定到被匹配对象的部分值,通过这个功能,就可以从枚举类型的变体中提取值。

看个例子:一位朋友正在尝试收集全部 50 个州 25 美分。当我们按硬币类型对零钱进行分类时,我们还会标出与每个25美分相关的州名称(美国州太多了,这里就只写了Alabama和Alaska这两个州)

#[derive(Debug)] // 便于打印调试 
enum UsState {  Alabama,  Alaska,  
}  enum Coin {  Penny,  Nickel,  Dime,  Quarter(UsState),  
}  fn value_in_cents(coin: Coin) -> u8 {  match coin {  Coin::Penny => {  println!("Lucky penny!");  1  },  Coin::Nickel => 5,  Coin::Dime => 10,  Coin::Quarter(state) => {  println!("State quarter from {:?}!", state);  25  }  }  
}  fn main() {  let c = Coin::Quarter(UsState::Alaska);  println!("{}", value_in_cents(c));  
}
  • 让25美分硬币(以下都叫Quarter)所对应的Coin里的变体,也就是Coin::Quarter给关联一个数据,它关联的数据就是上面的这个枚举类型UsState

  • value_in_cents函数里也需要对Quarter所在的分支稍微修改一下,匹配模式从Coin::Quarter修改到Coin::Quarter(state),意思就是把Coin::Quarter所关联的值绑定到state这个变量上,在后面的代码块里面就可以使用state这个变量,把Coin::Quarter所关联的值取出来进行使用。
    在某些情境下,Coin::Quarter所关联的值可能用不上,这时候就可以用通配符_代表不关心里面的内容:Coin::Quarter(_)

  • main函数里先声明了一个c变量,存的是Coin::Quarter(UsState::Alaska)。也就是存储了Coin::Quarter这个变体,然后其关联的值的是UsState::Alaska这个变体。最后又调用了一下value_in_cents函数。

看看输出效果:

State quarter from Alaska!
25

6.3.4. 匹配Option<T>

就以上一篇文章最后的代码例来做分析:

fn main() {  let x: i8 = 5;  let y: Option<i8> = Some(5);  let sum = match y {  Some(value) => x + value, // 如果 y 是 Some,则解包并相加  None => x,               // 如果 y 是 None,则返回 x    };  
}
  • 如果y不为None,就解包,把Some所关联的值绑定到value上,返回x + value的值
  • 如果yNone,就只返回x的值

6.3.5. match匹配必须穷举所有可能

Rust要求match覆盖到所有的可能性,这样才能保证代码的安全有效。

以上一个代码为基础稍作修改:

fn main() {  let x: i8 = 5;  let y: Option<i8> = Some(5);  let sum = match y {  Some(value) => x + value,   };  
}

输出:

error[E0004]: non-exhaustive patterns: `None` not covered--> src/main.rs:5:21|
5   |     let sum = match y {|                     ^ pattern `None` not covered|
note: `Option<i8>` defined here--> /Users/stanyin/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:571:1|
571 | pub enum Option<T> {| ^^^^^^^^^^^^^^^^^^
...
575 |     None,|     ---- not covered= note: the matched value is of type `Option<i8>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown|
6   ~         Some(value) => x + value,
7   ~         None => todo!(),|

Rust捕捉到了None这个可能性没有被覆盖的错误,所以报错。把处理None的分支加上就没问题了。

如果可能性太多或者不想处理其中一些可能性,这个时候就可以使用通配符_

6.3.6. 通配符

首先要把想处理的分支照常写上,其他的使用通配符_代替即可。

看例子:v是一个u8类型的变量,判断v是否是0

use rand::Rng;  // 使用外部库
fn main(){  let v: u8 = rand::thread_rng().gen_range(0..=255);  // 生成随机数println!("{}", v);  match v {  0 => println!("zero"),  _ => println!("not zero"),  }  
}

u8有256个数256种可能,使用match自然是不可能每个数都写一个分支,所以,就可以为0写一个分支,其他的使用通配符_来代替。

输出:

136
not zero

相关文章:

【Rust自学】6.3. 控制流运算符-match

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 6.3.1. 什么是match match允许一个值与一系列模式进行匹配&#xff0c;并执行匹配的模式对应的代码。模式可以是字面值、变量名、通配符等…...

大模型应用技术系列(三): 深入理解大模型应用中的Cache:GPTCache

前言 无论在什么技术栈中,缓存都是比较重要的一部分。在大模型技术栈中,缓存存在于技术栈中的不同层次。本文将主要聚焦于技术栈中应用层和底层基座之间中间件层的缓存(个人定位),以开源项目GPTCache(LLM的语义缓存)为例,深入讲解这部分缓存的结构和关键实现。 完整技术…...

『大模型笔记』评估大型语言模型的指标:ELO评分,BLEU,困惑度和交叉熵介绍以及举例解释

评估大型语言模型的指标:ELO评分,BLEU,困惑度和交叉熵介绍以及举例解释 文章目录 一. ELO Rating大模型的elo得分如何理解1. Elo评分的基本原理2. 示例说明3. 大模型中的Elo得分总结3个模型之间如何比较计算,给出示例进行解释1. 基本原理扩展到三方2. 示例计算第一场: A A…...

深度解析:Maven 和 Gradle 的使用比较及常见仓库推荐

Maven 和 Gradle 是 Java 项目中最常用的构建工具。它们各有优势&#xff0c;适用于不同的场景。本文将对两者进行详细的对比&#xff0c;并推荐一些常用的 Maven 和 Gradle 仓库&#xff0c;帮助开发者高效管理依赖。 一、Maven 和 Gradle 的使用比较 1.1 基本介绍 Maven 基…...

SQLite本地数据库的简介和适用场景——集成SpringBoot的图文说明

前言&#xff1a;现在项目普遍使用的数据库都是MySQL&#xff0c;而有些项目实际上使用SQLite既足矣。在一些特定的项目中&#xff0c;要比MySQL更适用。 这一篇文章简单的介绍一下SQLite&#xff0c;对比MySQL的优缺点、以及适用的项目类型和集成SpringBoot。 1. SQLite 简介 …...

管理面板Ajenti的在Windows10下Ubuntu24.04/Ubuntu22.04里的安装

Ajenti是一款基于Web的开源系统管理控制面板&#xff0c;可用于通过Web浏览器&#xff0c;管理远程系统管理性任务&#xff0c;这一点与 Webmin模块 非常相似。 Ajenti是一款功能非常强大的轻型工具&#xff0c;它提供了快速的、反应灵敏的Web界面&#xff0c;可用于管理小型服…...

在Python如何用Type创建类

文章目录 一&#xff0c;如何创建类1&#xff1a;创建一个简单类2&#xff1a;添加属性和方法3&#xff1a;动态继承父类4&#xff1a;结合元类的使用总结 二.在什么情境下适合使用Type创建类1. **运行时动态生成类**2. **避免重复代码**3. **依赖元类或高级元编程**4. **动态扩…...

Android学习19 -- NDK4--共享内存(TODO)

在安卓的NDK&#xff08;Native Development Kit&#xff09;中&#xff0c;C共享内存通常用于不同进程间的通信&#xff0c;或者在同一进程中多线程之间共享数据。这种方法相较于其他形式的IPC&#xff08;进程间通信&#xff09;来说&#xff0c;具有更高的性能和低延迟。共享…...

《Cocos Creator游戏实战》非固定摇杆实现原理

为什么要使用非固定摇杆 许多同学在开发摇杆功能时&#xff0c;会将摇杆固定在屏幕左下某一位置&#xff0c;不会让其随着大拇指触摸点改变&#xff0c;而且玩家只有按在了摇杆上才能移动人物&#xff08;触摸监听事件在摇杆精灵上)。然而&#xff0c;不同玩家的大拇指长度不同…...

RabbitMQ工作模式(详解 工作模式:简单队列、工作队列、公平分发以及消息应答和消息持久化)

文章目录 十.RabbitMQ10.1 简单队列实现10.2 Work 模式&#xff08;工作队列&#xff09;10.3 公平分发10.4 RabbitMQ 消息应答与消息持久化消息应答概念配置 消息持久化概念配置 十.RabbitMQ 10.1 简单队列实现 简单队列通常指的是一个基本的消息队列&#xff0c;它可以用于…...

【VScode】第三方GPT编程工具-CodeMoss安装教程

一、CodeMoss是什么&#xff1f; CodeMoss是一款集编程、学习和办公于一体的高效工具。它兼容多种主流平台&#xff0c;包括VSCode、IDER、Chrome插件、Web和APP等&#xff0c;支持插件安装&#xff0c;尤其在VSCode和IDER上的表现尤为出色。无论你是编程新手还是资深开发者&a…...

在JavaScript中,let 和 const有什么不同

在JavaScript中&#xff0c;let 和 const 是用于声明变量的关键字&#xff0c;但它们有一些重要的区别 1.重新赋值&#xff1a; let 声明的变量可以重新赋值。const 声明的变量必须在声明时初始化&#xff0c;并且之后不能重新赋值 let a 10; a 20; // 有效&#xff0c;a 的…...

Mysq学习-Mysql查询(4)

5.子查询 子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL4.1开始引入.在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表. 子查询中常用的操作符有ANY(SOME),ALL,IN,EXISTS.子查询可以添加到SELECT,UPD…...

安装torch-geometric库

目录 1.查看 torch 和 CUDA 版本 2.依次下载和 torch 和 CUDA 对应版本的四个依赖库pyg-lib、torch-scatter、torch-sparse、torch-cluster以及torch-spline-conv 3.下载并安装torch-geometric库 1.查看 torch 和 CUDA 版本 查看CUDA版本 nvcc -V 查看pytorch版本 pip s…...

Java数组深入解析:定义、操作、常见问题与高频练习

一、数组的定义 1. 什么是数组 数组是一个容器&#xff0c;用来存储多个相同类型的数据。它属于引用数据类型&#xff0c;可以存储基本数据类型&#xff08;如int、char&#xff09;或者引用数据类型&#xff08;如String、对象&#xff09;。 2. 数组的定义方式 a. 动态初…...

Docker-构建自己的Web-Linux系统-镜像webtop:ubuntu-kde

介绍 安装自己的linux-server,可以作为学习使用&#xff0c;web方式访问&#xff0c;基于ubuntu构建开源项目 https://github.com/linuxserver/docker-webtop安装 docker run -d -p 1336:3000 -e PASSWORD123456 --name webtop lscr.io/linuxserver/webtop:ubuntu-kde登录 …...

【C语言练习(17)—输出杨辉三角形】

C语言练习&#xff08;17&#xff09; 文章目录 C语言练习&#xff08;17&#xff09;前言题目题目解析整体代码 前言 杨辉三角形的输出可以分三步&#xff0c;第一步构建一个三角形、第二步根据规律将三角形内容填写、第三步将三角形以等腰的形式输出 题目 请输出一个十行的…...

SpringMVC学习(二)——RESTful API、拦截器、异常处理、数据类型转换

一、RESTful (一)RESTful概述 RESTful是一种软件架构风格&#xff0c;用于设计网络应用程序。REST是“Representational State Transfer”的缩写&#xff0c;中文意思是“表现层状态转移”。它基于客户端-服务器模型和无状态操作&#xff0c;以及使用HTTP请求来处理数据。RES…...

React 第二十节 useRef 用途使用技巧注意事项详解

简述 useRef 用于操作不需要在视图上渲染的属性数据&#xff0c;用于访问真实的DOM节点&#xff0c;或者React组件的实例对象&#xff0c;允许直接操作DOM元素或者是组件&#xff1b; 写法 const inpRef useRef(params)参数&#xff1a; useRef(params)&#xff0c;接收的 …...

VIVO Java开发面试题及参考答案

TCP 能不能两次握手? TCP 不能两次握手。 在 TCP 连接建立过程中,三次握手是必不可少的。第一次握手是客户端向服务器发送一个带有 SYN(同步序列号)标志的 TCP 报文段,这个报文段包含了客户端初始的序列号。这一步的主要目的是告诉服务器,客户端想要建立连接,并且让服务…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...