rust流程控制
一、分支
(一)if
1.if
语法格式
if boolean_expression {
}
例子
fn main(){let num:i32 = 5;if num > 0 {println!("正数");}
}
条件表达式不需要用小括号。
条件表达式必须是bool类型。
2.if else
语法格式
if boolean_expression {
} else {
}
例子
fn main() {let num = 12;if num % 2==0 {println!("偶数");} else {println!("奇数");}
}
if else既可以作语句,又可以作表达式。当作表达式时,它的值是其分支代码块最后一个表达式的值。
我们可以在 let 语句的右侧使用它,例如:
fn main() {let condition = true;let number = if condition { 5 } else { 6 };println!("The value of number is: {number}");
}
值取决于哪个代码块被执行。这意味着 if 的每个分支的可能的返回值都必须是相同类型;
在上例中,if 分支和 else 分支的结果都是 i32 整型。如果它们的类型不匹配,如下面这个例子,则会出现一个错误:
fn main() {let condition = true;let number = if condition { 5 } else { "six" };println!("The value of number is: {number}");
}
3.if else if
语法格式
if boolean_expression1 {
} else if boolean_expression2 {
} else {
}
例子
fn main() {let num = 2 ;if num > 0 {println!("{} is positive",num);} else if num < 0 {println!("{} is negative",num);} else {println!("{} is neither positive nor negative",num) ;}
}
(二)if let
句法
IfLetExpression :
if let Pattern = Expression BlockExpression
(else ( BlockExpression | IfExpression | IfLetExpression ) )?
1.if let
语法格式
if let Pattern = Expression {
}
Pattern就是模式。
如果Pattern与Expression匹配,就执行相应的代码块。
可以使用操作符 | 指定多个模式。 这与match表达式中的 | 具有相同的语义
例子
enum E {X(u8),Y(u8),Z(u8),
}
let v = E::Y(12);
if let E::X(n) | E::Y(n) = v {assert_eq!(n, 12);
}
2.if let else
语法格式
if let Pattern = Expression {
} else {
}
例子
let dish = ("Ham", "Eggs");
if let ("Bacon", b) = dish {println!("Bacon is served with {}", b);
} else {println!("No bacon will be served");
}
if let else与if else一样既可以作语句,又可以作表达式。当作表达式时,它的值是其分支代码块最后一个表达式的值。
fn main() {let x = Some(3);let a = if let Some(1) = x { 1 } else { 5 };println!("{a}");
}
3.if let else if let
语法格式
if let Pattern1 = Expression1 {
} else if let Pattern2 = Expression2 {
}else {
}
4.if和if let混合使用
语法格式
if let Pattern = Expression {
} else if boolean_expression{
}else {
}
例子
let x = Some(3);
let a = if let Some(1) = x {1
} else if x == Some(2) {2
} else if let Some(y) = x {y
} else {-1
};
assert_eq!(a, 3);
5.if let等价于match
例如:
if let PATS = EXPR {/* body */
} else {/*else */
}
等价于
match EXPR {PATS => { /* body */ },_ => { /* else */ }, // 如果没有else块,这相当于 `()`
}
在一些场合下,用match并不优雅,因为match必须考虑所有可能的值。
比如:
let optional = Some(7);
match optional {Some(i) => {println!("This is a really long string and `{:?}`", i);},_ => {}, // 必须有,因为 `match` 需要覆盖全部情况。不觉得这行很多余吗?
};
if let在这样的场合要简洁得多
fn main() {let number = Some(7);if let Some(i) = number {println!("Matched {:?}!", i);}
}
另一个好处是:if let允许匹配枚举非参数化的变量,即枚举未注明 #[derive(PartialEq)],我们也没有为其实现PartialEq。在这种情况下,通常if Foo::Bar==a会出错,因为此类枚举的实例不具有可比性。但是,if let是可行的。
你想挑战一下吗?使用if let修复以下示例:
// 该枚举故意未注明 `#[derive(PartialEq)]`,
// 并且也没为其实现 `PartialEq`。这就是为什么下面比较 `Foo::Bar==a` 会失败的原因。
enum Foo {Bar}fn main() {let a = Foo::Bar;// 变量匹配Foo::Barif Foo::Bar == a {// ^-- 这就是编译时发现的错误。使用 `if let` 来替换它。println!("a is foobar");}
}
(三)match
match用于检查值是否匹配一组模式中的某一个。似于C语言中的 switch 语句
语法格式
match variable_expression {pattern1 => {},pattern2 => {// },_ => {// 默认}
};
例子
fn main() {let x = 1;match x {1 => println!("one"),2 => println!("two"),3 => println!("three"),4 => println!("four"),5 => println!("five"),_ => println!("something else"),}
}
match既可以作语句,也可以作表达式,作表达式时,它把匹配分支代码块的最后一条表达式的结果当作返回值。
例子
fn main(){let state_code = "MH";let state = match state_code {"MH" => "Maharashtra","KL" => "Kerala","KA" => "Karnadaka","GA" => "Goa",_ => "Unknown"};println!("State name is {}",state);
}
运行结果
State name is Maharashtra
模式守卫
守卫出现在模式的后面,由关键字if后面的布尔类型表达式组成。
当模式匹配成功时,将执行守卫表达式。 只有此表达式的计算结果为真,才认为完全匹配成功。 否则,匹配将测试下一个模式,包括测试同一分支中运算符 | 分割的后续模式。
fn main() {let maybe_digit = Some(8);match maybe_digit {Some(x) if x < 10 => println!("digit < 10"),Some(x) => println!("digit >= 10"),None => panic!(),};
}
注意:使用操作符 | 的分支可能会导致后跟的守卫必须多次执行的副作用。 例如:
use std::cell::Cell;
let i = Cell::new(0i32);
match 1 {1 | _ if { i.set(i.get() + 1); false } => {}_ => {}
}
assert_eq!(i.get(), 2);
二、循环
(一)for
Rust 中的 for 只有 for in 这种格式,常用于遍历容器的元素
句法
IteratorLoopExpression :
for Pattern in Expression BlockExpression
pattern就是模式
例子
下面的代码,使用 for…in 循环,重复输出1到11之间的数字(不包括11)
fn main(){for x in 1..11{println!("x is {}",x);}
}
fn main() {let a = [10, 20, 30, 40, 50];for element in a {println!("the value is: {element}");}
}
(二)while
句法
PredicateLoopExpression :
while Expression BlockExpression
例子
下面的代码,使用 while 循环重写下上面的代码,重复输出1到11之间的数字(不包括11)
fn main(){let mut x = 1;while x < 11{println!("inside loop x value is {}",x);x+=1;}println!("outside loop x value is {}",x);
}
(三)loop
loop 语句代表着一种死循环。
语法格式
loop {
}
范例
下面的语句,我们使用 loop 输出1到无限大的数字。
fn main(){let mut x = 0;loop {x+=1;println!("x={}",x);}
}
(四)while let
句法
PredicatePatternLoopExpression :
while let Pattern = Expression BlockExpression
Pattern就是模式
如果值与模式匹配,则执行循环体块。如果不匹配,则跳出循环。
可以使用操作符 | 指定多个模式。
let mut vals = vec![2, 3, 1, 2, 2];
while let Some(v @ 1) | Some(v @ 2) = vals.pop() {// 打印2, 2, 然后1println!("{}", v);
}
例子
let mut x = vec![1, 2, 3];
while let Some(y) = x.pop() {println!("y = {}", y);
}
while let _ = 5 {println!("不可反驳模式总是会匹配成功");break;
}
while let等价于包含match的loop。
如下:
while let PATS = EXPR {/* loop body */
}
等价于
loop {match EXPR {PATS => { /* loop body */ },_ => break,}
}
三、循环标签
句法
LoopLabel :
LIFETIME_OR_LABEL :
一个循环表达式可以选择设置一个标签。这类标签被标记为循环表达式之前的生存期(标签),如 'foo: loop { break 'foo; }、'bar: while false {}、'humbug: for _ in 0…0 {}。 如果循环存在标签,则嵌套在该循环中的带此标签的break表达式和continue表达式可以退出此标签标记的循环层或将控制流返回至此标签标记的循环层的头部。
四、跳出循环
(一)break
句法
BreakExpression :
break LIFETIME_OR_LABEL? Expression?
当遇到break时,相关的循环体的执行将立即结束,例如:
let mut last = 0;
for x in 1..100 {if x > 12 {break;}last = x;
}
assert_eq!(last, 12);
break表达式只能跳出一层循环,如果要跳出多层循环,就要使用循环标签。
例如:
'outer: loop {while true {break 'outer;}
}
break表达式只允许在循环体内使用,它有break、break 'label、break EXPR、break 'label EXPR这四种形式。
fn main(){let mut x = 0;loop {x+=1;if x > 10 {break;}println!("x={}",x);}
}
break 可以返回值
当使用loop循环时,可以使用break表达式从循环中返回一个值,通过形如break EXPR或break 'label EXPR来返回,其中EXPR是一个表达式。
其后不跟表达式的break与后跟 () 的break效果相同。
例如:
let (mut a, mut b) = (1, 1);
let result = loop {if b > 10 {break b;}let c = a + b;a = b;b = c;
};
// 斐波那契数列中第一个大于10的值:
assert_eq!(result, 13);
(二)continue
句法
ContinueExpression :
continue LIFETIME_OR_LABEL?
当遇到continue时,相关的循环体的当前迭代将立即结束,并将控制流返回到循环头。 在while循环的情况下,循环头是控制循环的条件表达式。 在for循环的情况下,循环头是控制循环的调用表达式。
与break一样,continue只能跳过一层循环,如果要跳过多层,可以使用continue 'label。
continue表达式只允许在循环体内部使用。
fn main(){for x in 1..11{if 5 == x {continue;}println!("x is {}",x);}
}
相关文章:

rust流程控制
一、分支 (一)if 1.if 语法格式 if boolean_expression { }例子 fn main(){let num:i32 5;if num > 0 {println!("正数");} }条件表达式不需要用小括号。 条件表达式必须是bool类型。 2.if else 语法格式 if boolean_expression { } …...

虚拟机软件Parallels Desktop 19 mac功能介绍
Parallels Desktop 19 mac是一款虚拟机软件,它允许用户在Mac电脑上同时运行Windows、Linux和其他操作系统。Parallels Desktop提供了直观易用的界面,使用户可以轻松创建、配置和管理虚拟机。 PD19虚拟机软件具有快速启动和关闭虚拟机的能力,让…...

在工业机器视觉领域中应用钡铼技术有限公司的EtherCAT网关
钡铼技术有限公司作为一家专注于业物联网关、工业智能网关、边缘计算网关、ARM嵌入式工业计算机、PLC远程采集网关、Modbus转MQTT网关、OPC UA网关、BACnet网关路由器、Lora网关、工业4G边缘路由器、4G无线远程数据采集模块、4G DTU RTU、以太网远程IO模块、工业总线分布式I/O模…...

ssh指定的密钥协商方式以及Ansible的hosts文件修改密钥协商方式
一、首先你要知道用什么加密协商。 [WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details 10.10.2.190 | UNREACHABLE! > {"changed": false,"msg": "Failed to connect to the host via ssh: U…...

NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
自然语言处理是机器学习和人工智能的一个迷人领域。这篇博客文章启动了一个具体的 NLP 项目,涉及使用维基百科文章进行聚类、分类和知识提取。灵感和一般方法源自《Applied Text Analysis with Python》一书。 一、说明 该文是系列文章,揭示如何对爬取文…...

QT sqlite的简单用法
1、相关头文件 #include <QSqlDatabase> #include <QSqlError> #include <QSqlQuery> #include <QSqlRecord> #include <QSqlIndex> #include <QSqlField> #include <QFile> #include <QDebug> 2、数据库对象 QSqlDatabas…...

大模型部署手记(12)LLaMa2+Chinese-LLaMA-Plus-2-7B+Windows+text-gen+中文对话
1.简介: 组织机构:Meta(Facebook) 代码仓:https://github.com/facebookresearch/llama 模型:chinese-alpaca-2-7b-hf 下载:使用百度网盘下载 硬件环境:暗影精灵7Plus Windows版…...

C#导出本机Win32native dll
C# 使用 "3f/DllExport" 工具导出C风格的本机函数 [文 / 张赐荣] 首先,让我们来了解一下什么是争渡读屏软件,以及什么是争渡文本预处理API。争渡读屏软件是一款屏幕朗读软件,用于协助视力障碍人士操作电脑。 争渡文本预处理API是一…...

express-generator快速构建node后端项目
express-generator是express官方团队开发者准备的一个快速生成工具,可以非常快速的生成一个基于express开发的框架基础应用。 npm安装 npm install express-generator -g初始化应用 express my_node_test 创建了一个名为 my_node_test 的express骨架项目通过 Exp…...

视频监控系统/视频汇聚平台EasyCVR如何反向代理进行后端保活?
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

金融信创黄金三年:小程序生态+跨端技术框架构建
小程序应用场景生态的发展,受益于开源技术的发展,以及响应快速开发的实际业务需求,一些跨端框架如:Electron、wxPython、FinClip、Tauri、Flutter等发展也非常迅速,小程序生态跨端技术框架,不仅能满足自有超…...

这短短 6 行代码你能数出几个bug?
前言:本文仅仅只是分享笔者一年前见到的诡异代码,大家可以看看乐子,随便数一数一共有多少个bug,这数bug多少还是要点水平的 在初学编程的时候,写的第一个代码大多都是 hello world,可是就算是 hello world…...

【毕设选题】深度学习 机器视觉 车位识别车道线检测 - python opencv
0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过…...

不同数据类型在单片机内存中占多少字节?
文章目录 前言一、不同编译器二、C51* 指针型 三、sizeof结构体联合体 前言 在C语言中,数据类型指的是用于声明不同类型的变量或者函数的一个广泛的系统。变量的类型决定了变量存储占用的空间 一、不同编译器 类型16位编译器大小32位编译器大小64位编译器大小char…...

安卓LinearLayout让控件居中的办法
在控件属性上,是处理不了的。必须是在LinearLayout处理: 垂直居中 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width&…...

uniapp下拉刷新
为什么要使用uniapp的下拉刷新呢 跨平台兼容性: Uniapp 允许你一次编写代码,然后在多个平台(如微信小程序、H5、iOS 和 Android 等)上运行。使用 Uniapp 的下拉刷新功能,可以确保在不同平台上都能提供一致的用户体验&a…...

【工作记录】css3 grid布局笔记
概述 Grid 布局即网格布局,是一种新的 CSS 布局模型,比较擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系。号称是最强大的的 CSS 布局方案,是目前唯一一种 CSS 二维布局 参数配置说明 属性说明可…...

区块链技术-比特币数据结构
背景 随着近几年区块链技术的迅速发展,越来越多的行业正在将区块链技术应用到实际中去。例如,金融、物流、交易所等行业都开始尝试使用区块链技术来替代传统技术。伴随着区块链迅速发展的期间,诞生了比特币(BTC)、以太…...

SpringBoot结合dev-tool 实现IDEA项目热部署
什么是热部署? 应用正在运行的时候升级功能, 不需要重新启动应用对于Java应用程序来说, 热部署就是在运行时更新Java类文件 通俗的来讲,应用在运行状态下,修改项目源码后,不用重启应用,会把编译的内容部署到服务器上…...

flink中使用外部定时器实现定时刷新
背景: 我们经常会使用到比如数据库中的配置表信息,而我们不希望每次都去查询db,那么我们就想定时把db配置表的数据定时加载到flink的本地内存中,那么如何实现呢? 外部定时器定时加载实现 1.在open函数中进行定时器的…...

Spring Cloud Pipelines 入门实践
文章目录 1. 前言2. Spring Cloud Pipelines 是做什么的2.1. 预定义的流程2.2. 集成测试和契约测试2.3.部署策略 4. Spring Cloud Pipelines的使用示例4.1. 创建一个Spring Boot应用4.2. 将代码托管到GitHub仓库4.3. 添加Spring Cloud Pipelines依赖4.4. 配置Spring Cloud Pipe…...

G1 GC详解及设置
一、概述 G1 GC,全称Garbage-First Garbage Collector,在JDK1.7中引入了G1 GC,从JAVA 9开始,G1 GC是默认的GC算法。通过-XX:UseG1GC参数来启用。G1收集器是工作在堆内不同分区上的收集器,分区既可以是年轻代也可以是老…...

GitHub详细教程
将代码推送到GitHub仓库涉及一系列的步骤。以下是详细的步骤说明: 创建一个新的仓库(如果还没有的话): 访问 GitHub。登录您的帐户。点击页面右上角的图标,然后选择“New repository”。填写仓库名称、描述等信息&…...

【小沐学Python】Python实现Web图表功能(Dash)
文章目录 1、简介2、安装3、功能示例3.1 Hello World3.2 连接到数据3.3 可视化数据3.4 控件和回调3.5 设置应用的样式3.5.1 HTML and CSS3.5.2 Dash Design Kit (DDK)3.5.3 Dash Bootstrap Components3.5.4 Dash Mantine Components 4、更多示例4.1 Basic Dashboard4.2 Using C…...

【RabbitMQ】docker rabbitmq集群 docker搭建rabbitmq集群
docker rabbitmq集群 docker搭建rabbitmq集群 RabbitMQ提供了两种常用的集群模式 1.普通集群模式 2.镜像集群模式 普通集群模式只能同步主节点上的交换机和队列信息,但对于队列中的消息不做同步,主节点宕机也不能进行切换(故障转移ÿ…...

Linux 网络驱动实验
本文章对Linux 网络驱动实验中的设备树进行介绍,Linux网络驱动程序比较复杂,只要学会应用。 1、I.MX6ULL 网络外设设备树 I.MX6ULL 有两个 10/100M 的网络 MAC 外设,因此 I.MX6ULL 网络驱动主要就是这两个网络 MAC 外设的驱动。 fec1…...

访问Apache Tomcat的虚拟主机管理页面
介绍 通过Tomcat Host Manager应用可以创建、删除、管理Tomcat内的虚拟主机(virtual hosts)。该应用是Tomcat安装的一部分,默认在<Tomcat安装目录>/webapps/host-manager: 配置用户名、密码、角色 要访问Host Manager应…...

【算法】排序——归并排序和计数排序
主页点击直达:个人主页 我的小仓库:代码仓库 C语言偷着笑:C语言专栏 数据结构挨打小记:初阶数据结构专栏 Linux被操作记:Linux专栏 LeetCode刷题掉发记:LeetCode刷题 算法头疼记:算法专栏…...

discuz封面设置失败的解决办法(centos系统+windows系统)
discuz封面设置失败的解决办法(centos系统windows系统) centos系统:1、开启/var/www/html 这个目录的读写权限chmod -R 777 /var/www/html然后重启httpd:service httpd restart如果discuz论坛发布帖子,还是显示封面设置失败的话…...

AI绘画-Stable Diffusion笔记
软件:Stable Diffusion 视频教程来自 https://www.bilibili.com/video/BV1As4y127HW/?spm_id_from333.337.search-card.all.click 提示词 提示词类别 内容型提示词 人物主题特征: 服饰穿搭:white dress 发型发色:blonde hair,l…...