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

【Rust】——所有可能会用到模式的位置

💻博主现有专栏:

                C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等
🥏主页链接:

                Y小夜-CSDN博客

目录

🎯match分支

🎯if let 条件表达式

🎯while let条件循环

🎯for循环

🎯let语句

🎯函数参数


🎯match分支

        一个模式常用的位置是 match 表达式的分支。在形式上 match 表达式由 match 关键字、用于匹配的值和一个或多个分支构成,这些分支包含一个模式和在值匹配分支的模式时运行的表达式:

match VALUE {PATTERN => EXPRESSION,PATTERN => EXPRESSION,PATTERN => EXPRESSION,
}
match x {None => None,Some(i) => Some(i + 1),
}

这个 match 表达式中的模式为每个箭头左边的 None 和 Some(i)

 match 表达式必须是 穷尽exhaustive)的,意为 match 表达式所有可能的值都必须被考虑到。一个确保覆盖每个可能值的方法是在最后一个分支使用捕获所有的模式:比如,一个匹配任何值的名称永远也不会失败,因此可以覆盖所有匹配剩下的情况。

🎯if let 条件表达式

        以前讨论过了 if let 表达式,以及它是如何主要用于编写等同于只关心一个情况的 match 语句简写的。if let 可以对应一个可选的带有代码的 else 在 if let 中的模式不匹配时运行。

        这相比 match 表达式一次只能将一个值与模式比较提供了更多灵活性。并且 Rust 并不要求一系列 if letelse ifelse 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");}
}

        如果用户指定了中意的颜色,将使用其作为背景颜色。如果没有指定中意的颜色且今天是星期二,背景颜色将是绿色。如果用户指定了他们的年龄字符串并能够成功将其解析为数字的话,我们将根据这个数字使用紫色或者橙色。最后,如果没有一个条件符合,背景颜色将是蓝色。

        这个条件结构允许我们支持复杂的需求。使用这里硬编码的值,例子会打印出 Using purple as the background color

        注意 if let 也可以像 match 分支那样引入覆盖变量:if let Ok(age) = age 引入了一个新的覆盖变量 age,它包含 Ok 成员中的值。这意味着 if age > 30 条件需要位于这个代码块内部;不能将两个条件组合为 if let Ok(age) = age && age > 30,因为我们希望与 30 进行比较的被覆盖的 age 直到大括号开始的新作用域才是有效的。

  if let 表达式的缺点在于其穷尽性没有为编译器所检查,而 match 表达式则检查了。如果去掉最后的 else 块而遗漏处理一些情况,编译器也不会警告这类可能的逻辑错误。

🎯while let条件循环

它使用 vector 作为栈并以先进后出的方式打印出 vector 中的值:

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

        这个例子会打印出 3、2 接着是 1。pop 方法取出 vector 的最后一个元素并返回 Some(value)。如果 vector 是空的,它返回 Nonewhile 循环只要 pop 返回 Some 就会一直运行其块中的代码。一旦其返回 Nonewhile 循环停止。我们可以使用 while let 来弹出栈中的每一个元素。

🎯for循环

在 for 循环中,模式是 for 关键字直接跟随的值,正如 for x in y 中的 x

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

会打印:

$ cargo runCompiling patterns v0.1.0 (file:///projects/patterns)Finished dev [unoptimized + debuginfo] target(s) in 0.52sRunning `target/debug/patterns`
a is at index 0
b is at index 1
c is at index 2

🎯let语句

        在本章之前,我们只明确的讨论过通过 match 和 if let 使用模式,不过事实上也在别的地方使用过模式,包括 let 语句。例如,考虑一下这个直白的 let 变量赋值:

let x = 5;

        不过你可能没有发觉,每一次像这样使用 let 语句就是在使用模式!let 语句更为正式的样子如下:

let PATTERN = EXPRESSION;

        像 let x = 5; 这样的语句中变量名位于 PATTERN 位置,变量名不过是形式特别朴素的模式。我们将表达式与模式比较,并为任何找到的名称赋值。所以例如 let x = 5; 的情况,x 是一个代表 “将匹配到的值绑定到变量 x” 的模式。同时因为名称 x 是整个模式,这个模式实际上等于 “将任何值绑定到变量 x,不管值是什么”。

        为了更清楚的理解 let 的模式匹配方面的内容,考虑示例 18-4 中使用 let 和模式解构一个元组:

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

        这里将一个元组与模式匹配。Rust 会比较值 (1, 2, 3) 与模式 (x, y, z) 并发现此值匹配这个模式。在这个例子中,将会把 1 绑定到 x2 绑定到 y 并将 3 绑定到 z。你可以将这个元组模式看作是将三个独立的变量模式结合在一起。

        如果模式中元素的数量不匹配元组中元素的数量,则整个类型不匹配,并会得到一个编译时错误。

    let (x, y) = (1, 2, 3);

尝试编译这段代码会给出如下类型错误:

$ cargo runCompiling patterns v0.1.0 (file:///projects/patterns)
error[E0308]: mismatched types--> src/main.rs:2:9|
2 |     let (x, y) = (1, 2, 3);|         ^^^^^^   --------- this expression has type `({integer}, {integer}, {integer})`|         ||         expected a tuple with 3 elements, found one with 2 elements|= note: expected tuple `({integer}, {integer}, {integer})`found tuple `(_, _)`For more information about this error, try `rustc --explain E0308`.
error: could not compile `patterns` due to previous error

为了修复这个错误,可以使用 _ 或 .. 来忽略元组中一个或多个值

🎯函数参数

它获取一个 i32 类型的参数 x,现在这看起来应该很熟悉:

fn foo(x: i32) {// code goes here
}

x 部分就是一个模式!类似于之前对 let 所做的,可以在函数参数中匹配元组。

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

        这会打印出 Current location: (3, 5)。值 &(3, 5) 会匹配模式 &(x, y),如此 x 得到了值 3,而 y得到了值 5

相关文章:

  • Spring Cloud学习:如何实现Gateway 服务网关限流
  • ESP32 esp-idf esp-adf环境安装及.a库创建与编译
  • OpenCV颜色检测
  • 网络编程(六)TCP并发服务器
  • B3996 [洛谷 202406GESP 模拟 三级] 小洛的数字游戏
  • SpringMVC:拦截Mybatis的mapper
  • 如何设计高可用的淘客返利系统
  • Synchronized、volatile与ReentrantLock:比较这些同步机制在Java并发编程中的应用和区别
  • Spring响应式编程之Reactor操作符
  • Kubernetes 托管与非托管有哪些区别?应该怎么选型?
  • LeetCode:503. 下一个更大元素 II(Java 单调栈)
  • 如何在Web开发中创建、删除和修改按钮:实用指南
  • 华为仓颉语言:编程语言的新篇章
  • 说说MQ在你项目中的应用(一)
  • IOS开发学习日记(十六)
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 0x05 Python数据分析,Anaconda八斩刀
  • chrome扩展demo1-小时钟
  • Flannel解读
  • Fundebug计费标准解释:事件数是如何定义的?
  • GraphQL学习过程应该是这样的
  • HomeBrew常规使用教程
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Just for fun——迅速写完快速排序
  • MaxCompute访问TableStore(OTS) 数据
  • Python打包系统简单入门
  • React+TypeScript入门
  • springboot_database项目介绍
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • vue数据传递--我有特殊的实现技巧
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 从tcpdump抓包看TCP/IP协议
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 缓存与缓冲
  • 解析带emoji和链接的聊天系统消息
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 如何进阶一名有竞争力的程序员?
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 线上 python http server profile 实践
  • 因为阿里,他们成了“杭漂”
  • 用Visual Studio开发以太坊智能合约
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 从如何停掉 Promise 链说起
  • 国内开源镜像站点
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​2020 年大前端技术趋势解读
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • (06)金属布线——为半导体注入生命的连接
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)ssm码农论坛 毕业设计 231126
  • (排序详解之 堆排序)
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音