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

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...