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函数中进行定时器的…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...