Rust语言入门教程(五) - 流控制语句
if 表达式
在Rust中, if语句的判断条件不需要用( )括起来, 它会认为所有在if 和 {之间的表达式就是判断条件,例如:
if num == 5 {msg = "five";
}
判断条件的表达式必须返回一个bool型的值, 因为Rust是一个不喜欢进行强制类型转换的语言,绝大多数时候, Rust都不会对数据进行强制类型转换,也就是说,下面的例子是一个错误的范例:
if 1 {msg = "five"
}
如果要进行多分支的条件判断,可以使用else if (注意 else和if是分开的),最后也可以用else结尾, 例如:
if num == 5{msg = "five";
} else if num == 4 {msg = "four";
} else {msg = "other";
}
注意, if是一种表达式, 而不是语句。 语句不会返回值, 而表达式会返回值, 因此,上面的代码可以改写成这样:
msg = if num == 5{"five"
} else if num == 4 {"four"
} else {"other"
}; // 注意, 这是一个赋值语句, 语句应以 ; 结尾
注意,在上面的例子中,每个判断分支的结尾没有;, 因为这是一个尾部表达式, 用于给if表达式返回一个值;我们也不能使用return关键字, 而只能使用尾部表达式,因为return只能用于函数定义的代码块中,给函数返回结果;另外,每个判断分支返回的值的数据类型必须相同, 否则Rust编译器无法确定变量msg的数据类型; 在if表达式的最后有一个;, 因为整体来看, 这是一个赋值语句, 把if表达式的返回值赋值给了变量msg, 而Rust的语句应该以;结尾。
三元表达式?
Rust中没有三元表达式的设计, 例如在C语言中, 三元表达式形如:
num = a ? b : c;
虽然这种写法确实简单快捷, 但是即便这种简单的例子,其实也并不是特别易读和一目了然。如果事情稍微变得复杂一些, 加上一些三元表达式的嵌套, 看起来就更加的令人困惑了,比如:
num = a ? x ? y : z : c;
在Rust中我们选择抛弃三元表达式, 因为用if就已经能够简单的表达需求了, 比如:
num = if a {b} else {c};
即使存在一些嵌套也是比较简单易读的,
num = if a {if x {y} else {z}
} else {c
}
loop 循环
loop是无条件的循环, 与变量不可变的原因类似, Rust的这个设计的初衷, 也是考虑到编译器如果确定一个循环式无条件执行的情况下, 可以做更多的优化,从而获得更好的性能。
当然, 正如变量也需要改变,循环最终仍然是需要终结的。在Rust中,我们也使用break语句来跳出循环,例如:
loop {break;
}
但是如何跳出多层循环呢,比如:
loop {loop {loop {break;}}
}
默认情况下, 这只会跳出最内层的循环,如果我想跳出指定层级的循环应该怎么办呢?Rust允许我们给循环打标签,以便满足我们提到的这种需求, 标签的格式是'标签名(以一个'开头), 下面的例子展示了如何从让break语句跳出指定的循环:
'bob: loop {loop {loop {break 'bob;}}
}
最外层的循环被打上了一个名为'bob的标签, 而break 'bob语句告诉我们, 要跳出的正是这个'bob循环。与break的用法类型,continue语句通常用于跳过本次循环,进入到下一次循环, continue同样可以指定一个标签, 告诉代码下一次循环的入口在哪里, 例如:
'bob: loop {loop {continue 'bob;}
}
while 循环
while循环的行为和loop基本一致, 只是每次进行循环前, 都会进行条件判断, 当条件判断表达式的返回值为true时, 才会继续进行下一轮循环。 与if表达式的条件判断一样, 条件判断表达式的返回值必须为bool型, Rust不会为其他类型的返回值进行强制类型转换。格式如下:
while dizzy() {do_stuff()
}
用loop加上if, 也可以很容易的改写while表达式:
loop {if !dizzy() {break}do_stuff()
}
不要觉得这样做是不是因为我太无聊了,Rust中并没有do while的设计, 用上面的改写方法, 就可以轻松的实现do while的效果了:
loop {do_stuff()if !dizzy() {break}
}
for 循环
和大多数现代编程语言一样, Rust中的for循环会遍历一个可迭代对象中的每个值。复合数据类型和集合数据类型(collections)通常都会有一些方法来返回一个可迭代对象,用于for循环使用。
for num in [7, 8, 9].iter(){// do stuff with num
}
上面的例子中[7, 8, 9]这个数组调用了iter()函数来获取了一个迭代器,iter()这个函数也是通用的获取迭代器的方法。一些有序的数据类型的迭代器会有序的返回一组值, 但一些无序的数据类型的迭代器返回的值的顺序就是随机的了。
Rust的for循环中, 如果迭代器返回的是一组值, 那么for循环中也可以用一组变量来直接解构并接收返回的值,例如:
let a = [(1, 2), (3, 4)];
for (x, y) in a.iter() {// do stuff with x, y
}
还有一个常见的场景是在某个数字范围内进行for循环, 指定数字范围的格式是起始(闭)..结束(开) :
for num in 0..50 {// do stuff with num 1 to 49
}
如果想要包含结束的数字, 那么可以用这种格式起始(闭)..=结束(闭)
for num in 0..=50 {// do stuff with num 1 to 50
}
小结
本章介绍了if条件判断语句, 和几种循环语句的格式和使用场景, 下一章将介绍Rust中比较重要的一种数据类型,String。
相关文章:
Rust语言入门教程(五) - 流控制语句
if 表达式 在Rust中, if语句的判断条件不需要用( )括起来, 它会认为所有在if 和 {之间的表达式就是判断条件,例如: if num 5 {msg "five"; }判断条件的表达式必须返回一个bool型的值, 因为Rust是一个不喜…...
字符串:leetcode1410. HTML 实体解析器
1410. HTML 实体解析器 「HTML 实体解析器」 是一种特殊的解析器,它将 HTML 代码作为输入,并用字符本身替换掉所有这些特殊的字符实体。 HTML 里这些特殊字符和它们对应的字符实体包括: 双引号:字符实体为 " ÿ…...
springboot+vue项目如何集成onlyoffice开源文档组件
一、onlyoffice是什么 ONLYOFFICE 是一个开源的办公套件,适合多人在线协作。由总部位于总部在拉脱维亚的 IT 公司Acensio System SIA 开发。它提供在线协作文档编辑器(包括文档、电子表格、演示文稿和表单),适用于 Windows、Linu…...
Android okhttp3.0配置https信任所有证书
参考: Android okhttp3.0配置https的自签证书和信任所有证书 private OkHttpClient getHttpsClient() {OkHttpClient.Builder okhttpClient new OkHttpClient().newBuilder();//信任所有服务器地址okhttpClient.hostnameVerifier(new HostnameVerifier() {Overridepublic boo…...
大数据基础设施搭建 - Hive
文章目录 一、上传压缩包二、解压压缩包三、配置环境变量四、初始化元数据库4.1 配置MySQL地址4.2 拷贝MySQL驱动4.3 初始化元数据库4.3.1 创建数据库4.3.2 初始化元数据库 五、启动元数据服务metastore5.1 修改配置文件5.2 启动/关闭metastore服务 六、启动hiveserver2服务6.1…...
手把手教你安装 Visual Studio 2022 及其简单使用
软件下载 打开 Visual Studio 官网,个人选择免费的Community社区版就够用了。 软件安装 双击运行安装程序: 点击继续 即可: 等待加载完成: 可以看到 Visual Studio 2022 对应不同的开发需求提供了若干工作负载,这里以…...
在MySQL中,修改字段A相同的记录的字段B ,要使得字段C小的记录的字段B值等于字段C大的记录的字段B值
例如:更新具有相同电话号码的用户记录,使得updatetime小的记录的name值等于updatetime大的记录的name值。 首先,我们需要创建一个用户表,这个用户表包含以下字段:phone,updatetime, name。以下是创建这个表…...
Java WebSocket 客户端接收大量数据
介绍 WebSocket 是一种基于 TCP 协议的全双工通信协议,它能够在客户端和服务器之间建立一个持久连接,实现实时的双向数据传输。在实际应用中,有时候我们需要处理大量的数据,例如实时监控系统或者实时股票行情等。本文将介绍如何使…...
QT 在Windows下实现ping功能(ICMP)
前言 很多时候,我们可能会图省事直接调用系统中的ping命令,但这是很不科学的~ 废话不多说,直接上代码.. .pro文件 在.pro文件末尾添加一行: LIBS -liphlpapi -lws2_32 .h文件 在.h文件中加入: #include <Q…...
harmonyos应用开发者高级认证考试部分答案
1只要使用端云一体化的云端资源就需要支付费用(错) 2所有使用Component修饰的自定义组件都支持onPageShow,onBackPress和onPageHide生命周期函数。(错) 3 HarmonyOS应用可以兼容OpenHarmony生态(对&#…...
基于 STM32Cube.AI 的嵌入式人脸识别算法实现
本文介绍了如何使用 STM32Cube.AI 工具开发嵌入式人脸识别算法。首先,我们将简要介绍 STM32Cube.AI 工具和 STM32F系列单片机的特点。接下来,我们将详细讨论如何使用 STM32Cube.AI 工具链和相关库来进行人脸识别算法的开发和优化。最后,我们提…...
ElasticSearch之cat allocation API
查看各节点上各个shard的硬件使用情况,命令样例如下: curl -X GET "https://localhost:9200/_cat/allocation?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"执行结果如下&#x…...
Vue + Element UI 实现复制当前行数据功能(复制到新增页面组件值不能更新等问题解决)
1、需求 使用Vue Element UI 实现在列表的操作栏新增一个复制按钮,复制当前行的数据可以打开新增弹窗后亦可以跳转到新增页面,本文实现为跳转到新增页面。 2、实现 1)列表页 index.vue <el-table> <!-- 其他列 --> <el-t…...
嵌入式FPGA IP正在发现更广阔的用武之地
作者:郭道正, Achronix Semiconductor中国区总经理 在日前落幕的“中国集成电路设计业2023年会暨广州集成电路产业创新发展高峰论坛(ICCAD 2023)”上,Achronix的Speedcore™嵌入式FPGA硅知识产权(eFPGA IP)…...
[点云分割] 条件欧氏聚类分割
介绍 条件欧氏聚类分割是一种基于欧氏距离和条件限制的点云分割方法。它通过计算点云中点与点之间的欧氏距离,并结合一定的条件限制来将点云分割成不同的区域或聚类。 在条件欧氏聚类分割中,通常会定义以下两个条件来判断两个点是否属于同一个聚类&…...
Spring事务粒度优化与传播机制
在Spring事务中,我们通常会为了控制事务粒度,会把它进行拆分,为了避免大事务执行太久,占用资源太多,导致资源利用率低的问题。 我们曾经就遇到老系统因为大事务,把服务打死了。 问题出在一个大事务中有一…...
MySQL 基于成本的优化
其实在MySQL中⼀条查询语句的执⾏成本是由下边这两个⽅⾯组成的: I/O成本 我们的表经常使⽤的MyISAM、InnoDB存储引擎都是将数据和索引都存储到磁盘上的,当我们想查询表中的记录时,需要先把数据或者索引加载到内存中 然后再操作。这个从磁盘…...
【maven】【IDEA】idea中使用maven编译项目,报错java: 错误: 找不到符号 【2】
idea中使用maven编译项目,报错java: 错误: 找不到符号 错误状况展示: 如果报这种错,是因为项目中真的找不到报错的方法或者枚举 字段之类的,但实际是 : 点击 File Path...
AIGC,ChatGPT AI绘画 Midjourney 注册流程详细步骤
AI 绘画,Midjourney完成高清图片绘制,轻松掌握AI工具。 前期准备: ① 一个能使用的谷歌账号 ② 可以访问外网 Midjourney注册 1.进入midjourney官网https://www.midjourney.com 点击左下角”Join the Beta”,就可以注册,第一次使用的小伙伴会弹出提示,只需要点击Acc…...
万字解析设计模式之模板方法与解释器模式
一、模板方法模式 1.1概述 定义一个操作中算法的框架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
