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函数中进行定时器的…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
