【Rust练习】14.流程控制
练习题来自:https://practice-zh.course.rs/flow-control.html
1
// 填空
fn main() {let n = 5;if n < 0 {println!("{} is negative", n);} __ n > 0 {println!("{} is positive", n);} __ {println!("{} is zero", n);}
}
非常简单的if-else
fn main() {let n = 5;if n < 0 {println!("{} is negative", n);} else if n > 0 {println!("{} is positive", n);} else {println!("{} is zero", n);}
}
2 🌟🌟 if/else 可以用作表达式来进行赋值
// 修复错误
fn main() {let n = 5;let big_n =if n < 10 && n > -10 {println!(" 数字太小,先增加 10 倍再说");10 * n} else {println!("数字太大,我们得让它减半");n / 2.0 ;}println!("{} -> {}", n, big_n);
}
能通过if表达式直接赋值也是现代语言的一个新鲜玩意了,不知道为什么C++不打个补丁支持下。
fn main() {let n = 5;let big_n = if n < 10 && n > -10 {println!(" 数字太小,先增加 10 倍再说");10 * n} else {println!("数字太大,我们得让它减半");n / 2};println!("{} -> {}", n, big_n);
}
3 for in 可以用于迭代一个迭代器,例如序列 a…b.
fn main() {for n in 1..=100 { // 修改此行,让代码工作if n == 100 {panic!("NEVER LET THIS RUN")}}
}
始终记得Rust的range是一个左闭右开区间,想要包含右边就得加上等号就行,这里就要去掉。
fn main() {for n in 1..100 { // 修改此行,让代码工作if n == 100 {panic!("NEVER LET THIS RUN")}}
}
题外话:Rust 目前还是一个比较新的语言,主流的 IDE 为 VS Code(安装 rust-analyzer 插件)和 RustRover,前者无论商用还是非商用都是不收费的,后者非商用不收费,商用收费(应该是 Jetbrains 旗下第一个这么收费的,其他 IDE 都是任何使用都得收费)。下面提到的 VS Code 都指的是加载了 rust-analyzer 插件的。
就我个人的体验来看,两者各有各的长处。
这是 VS Code 的代码:

这是 Rustrover 的代码:

可以看到 VS Code 对变量的染色更充分一点,不过 Rustrover 对这个 range 的提示就很不错,你基本不可能认为会跑到 100。由于Rust存在类型推导的机制,因此当你不清楚变量的类型时,IDE提供的类型提示就尤为重要。这点 Rustrover 不如 VS Code,尤其是对于一些特征的推导,Rustrover 只能推导出基本类型,VS Code就能推导出impl trait。
另外如果你想阅读库代码时,Rustrover有个将注释文档排版的功能,非常不错:

VS Code这边可能是考虑到你用浏览器也能访问本地排版好的文档,就没有这个功能,少开一个浏览器还是省了不少事的。
我们接下来的代码都以 VS Code 为基准 IDE。
4
// 修复错误,不要新增或删除代码行
fn main() {let names = [String::from("liming"),String::from("hanmeimei")];for name in names {// do something with name...}println!("{:?}", names);let numbers = [1, 2, 3];// numbers中的元素实现了 Copy,因此无需转移所有权for n in numbers {// do something with name...}println!("{:?}", numbers);
}
string 不是基本类型,因此需要借用
fn main() {let names = [String::from("liming"),String::from("hanmeimei")];for name in &names {// do something with name...}println!("{:?}", names);let numbers = [1, 2, 3];// numbers中的元素实现了 Copy,因此无需转移所有权for n in numbers {// do something with name...}println!("{:?}", numbers);
}
5
fn main() {let a = [4,3,2,1];// 通过索引和值的方式迭代数组 `a` for (i,v) in a.__ {println!("第{}个元素是{}",i+1,v);}
}
固定用法了。
fn main() {let a = [4,3,2,1];// 通过索引和值的方式迭代数组 `a` for (i,v) in a.iter().enumerate() {println!("第{}个元素是{}",i+1,v);}
}
6 🌟🌟 当条件为 true 时,while 将一直循环
// 填空,让最后一行的 println! 工作 !
fn main() {// 一个计数值let mut n = 1;// 当条件为真时,不停的循环while n __ 10 {if n % 15 == 0 {println!("fizzbuzz");} else if n % 3 == 0 {println!("fizz");} else if n % 5 == 0 {println!("buzz");} else {println!("{}", n);}__;}println!("n 的值是 {}, 循环结束",n);
}
这道题应该是拿大名鼎鼎的 Fizzbuzz 题目改的。
fn main() {// 一个计数值let mut n = 1;// 当条件为真时,不停的循环while n < 10 {if n % 15 == 0 {println!("fizzbuzz");} else if n % 3 == 0 {println!("fizz");} else if n % 5 == 0 {println!("buzz");} else {println!("{}", n);}n += 1;}println!("n 的值是 {}, 循环结束", n);
}
我就顺便把这道题做了吧,应该是我用Rust写的第一道算法题,之前用C++写过一遍。Fizzbuzz题目如下:
给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:
answer[i] == “FizzBuzz” 如果 i 同时是 3 和 5 的倍数。
answer[i] == “Fizz” 如果 i 是 3 的倍数。
answer[i] == “Buzz” 如果 i 是 5 的倍数。
answer[i] == i (以字符串形式)如果上述条件全不满足。
这里用 LeetCode 的提交格式:
impl Solution {pub fn fizz_buzz(n: i32) -> Vec<String> {let mut i = 1;let mut res: Vec<String> = Vec::new();while i <= n {if i % 15 == 0 {res.push("FizzBuzz".to_string());} else if i % 3 == 0 {res.push("Fizz".to_string());} else if i % 5 == 0 {res.push("Buzz".to_string());} else {res.push(i.to_string());}i += 1;}res}
}
7 🌟 使用 break 可以跳出循环
// 填空,不要修改其它代码
fn main() {let mut n = 0;for i in 0..=100 {if n == 66 {__}n += 1;}assert_eq!(n, 66);
}
答案
fn main() {let mut n = 0;for _ in 0..=100 {if n == 66 {break;}n += 1;}assert_eq!(n, 66);
}
8 🌟 continue 会结束当次循环并立即开始下一次循环
// 填空,不要修改其它代码
fn main() {let mut n = 0;for i in 0..=100 {if n != 66 {n+=1;__;}__}assert_eq!(n, 66);
}
答案
// 填空,不要修改其它代码
fn main() {let mut n = 0;for i in 0..=100 {if n != 66 {n+=1;continue;}break;}assert_eq!(n, 66);
}
9 🌟🌟 loop 一般都需要配合 break 或 continue 一起使用。
// 填空,不要修改其它代码
fn main() {let mut count = 0u32;println!("Let's count until infinity!");// 无限循环loop {count += 1;if count == 3 {println!("three");// 跳过当此循环的剩余代码__;}println!("{}", count);if count == 5 {println!("OK, that's enough");__;}}assert_eq!(count, 5);
}
答案
fn main() {let mut count = 0u32;println!("Let's count until infinity!");// 无限循环loop {count += 1;if count == 3 {println!("three");// 跳过当此循环的剩余代码continue;;}println!("{}", count);if count == 5 {println!("OK, that's enough");break;}}assert_eq!(count, 5);
}
C++是没有loop(无限循环)的,很多其他的语言也没有,原因很明显,无限循环一旦不写终止条件,很容易就成了死循环。而Rust的编译器也没有智能到检测到死循环的存在,比如这里注释掉第二个if的break,loop直接就死循环了,编译器也是很老实地跑,没有任何报错或者警告。倒是VS Code给了一个代码不可达(unreachable)的提示。

所以我不是很建议在代码里使用loop。
10 🌟🌟 loop 是一个表达式,因此我们可以配合 break 来返回一个值
fn main() {let mut counter = 0;let result = loop {counter += 1;if counter == 10 {__;}};assert_eq!(result, 20);
}
很有意思的设计,C++实现类似功能估计要多写点代码——包个函数就有入栈出栈的性能损耗,直接修改又不容易让人意识到变量已经被修改了。
fn main() {let mut counter = 0;let result = loop {counter += 1;if counter == 10 {break counter;}};assert_eq!(result, 20);
}
11 🌟🌟🌟 当有多层循环时,你可以使用 continue 或 break 来控制外层的循环。要实现这一点,外部的循环必须拥有一个标签 'label, 然后在 break 或 continue 时指定该标签
// 填空
fn main() {let mut count = 0;'outer: loop {'inner1: loop {if count >= 20 {// 这只会跳出 inner1 循环break 'inner1; // 这里使用 `break` 也是一样的}count += 2;}count += 5;'inner2: loop {if count >= 30 {break 'outer;}continue 'outer;}}assert!(count == __)
}
答案
// 填空
fn main() {let mut count = 0;'outer: loop {'inner1: loop {if count >= 20 {// 这只会跳出 inner1 循环break 'inner1; // 这里使用 `break` 也是一样的}count += 2;}count += 5;'inner2: loop {if count >= 30 {break 'outer;}continue 'outer;}}assert!(count == 30)
}
对比其他语言的goto,Rust的这个弱化了一点,仅仅能对循环打label,但是这已经让人不好走查代码了。我的建议也是:不要用。几乎所有编程书在介绍语言里的goto时都不建议使用,用起来很爽,看代码很痛苦。
相关文章:
【Rust练习】14.流程控制
练习题来自:https://practice-zh.course.rs/flow-control.html 1 // 填空 fn main() {let n 5;if n < 0 {println!("{} is negative", n);} __ n > 0 {println!("{} is positive", n);} __ {println!("{} is zero", n);} } …...
React-Hooks-Form 集成 Zod 校验库
React-Hooks-Form 集成 Zod 校验库 首先需要安装 react hooks form 官方提交的解析器 npm install hookform/resolvers再安装校验库 npm install zod它不仅支持 Zod 校验库同时还支持目前各种主流的校验库比如:Yup、Zod、Joi、Ajv、Vest、Custom 具体查看官方文…...
kettle从入门到精通 第八十五课 ETL之kettle kettle中javascript步骤调用外部javascript/js文件
场景:交流学习群里面有小伙伴咨询kettle中的javascript代码步骤如何调用外部js文件中的函数,觉得有点意思的,于是就抽时间整理了一下。 1、外部js文件为test.js,代码如下: function test(param){return "接收到了…...
比传统机器学习更先进的深度学习神经网络的二分类建模全流程教程
比传统机器学习更先进的深度学习神经网络的二分类建模全流程分析教程 深度学习介绍和与传统机器学习的区别 深度学习(Deep Learning)是一种机器学习的分支,基于多层神经网络模型,能够自动从大量数据中学习特征并进行预测。深度学…...
TeamTalk梳理概括
文章目录 即时通讯重点概括展开聊聊单聊消息流转流程展开聊聊群聊消息流转流程群成员管理数据库MySQL连接池设计redis连接池设计文件传输原理实时性并发能力 db_proxy_server reactor响应处理流程单聊消息消息如何封装?如何保证对端完整解析一帧消息?协议…...
构建“零工市场小程序”,服务灵活就业“大民生”
如今,灵活就业已成为现代劳动力市场的重要组成部分。然而,这一就业形态也面临着信息不对称、匹配效率低下等一系列挑战。为有效解决这些问题,构建一个高效、便捷的“零工市场小程序”显得尤为重要。 二、零工市场现状与挑战 市场规模与增长趋…...
【组件】前端js HEIC/HEIF 转换为JPEG、PNG或GIF格式 苹果格式
【组件】前端js HEIC/HEIF 转换为JPEG、PNG或GIF格式 Heic2any: Client-side conversion of HEIC/HEIF image files to JPEG,PNG, or GIF in the browser.https://alexcorvi.github.io/heic2any/#demo GitHub - alexcorvi/heic2any: Converting HEIF/HEIF image formats to PN…...
Vue3中slot插槽的几种使用实践
【1】默认插槽 父组件 <Category title"今日美食城市"><img :src"imgUrl" alt""> </Category>子组件 <div class"category"><h2>{{title}}</h2><slot>默认内容</slot> </div&g…...
SSH工具 MobaXterm的使用与快捷配置
软件下载/安装与链接服务器/本地虚拟机 文章目录 软件下载/安装与链接服务器/本地虚拟机软件下载软件安装使用软件链接非本地机器并设置用户密码我不想有确定密码的弹窗 其余便捷配置配置右键粘贴SSH链接设置 软件下载 如果你访问不了这个网址,可以评论区找博主或者…...
git 远程分支同步本地落后的有冲突的分支
如果你的本地分支已经修改了很多代码,但同时也已经落后于远程分支。这个时候你需要在主分支上拉最新的代码,然后切换到你的分支。 如主分支是 main ,从分支是xing。 首先切换到子分支 $ git checkout xing 然后请求merge主分支main的代码 …...
如何基于Java解析国密数字证书
一、说明 随着信息安全的重要性日益凸显,数字证书在各种安全通信场景中扮演着至关重要的角色。国密算法,作为我国自主研发的加密算法标准,其应用也愈发广泛。然而,在Java环境中解析使用国密算法的数字证书时,我们可能…...
java实现系统文件管理
java实现系统文件管理 环境:jdk17springbootVueElementUI 背景:公司所做的项目需要别的系统向我们服务器上传文件,当我们需要查看这些文件什么时候上传的、文件数据是怎样的,只能去机房,排查问题效率较低,…...
pytorch快速入门(一)—— 基本工具及平台介绍
前言 该pytorch学习笔记应该配合b站小土堆的《pytorch深度学习快速入门教程》使用 环境配置:Anaconda Python编译器:pycharm、jupyter 两大法宝函数 dir():知道包中有什么东西(函数 / 属性..…...
『功能项目』怪物的有限状态机【42】
本章项目成果展示 我们打开上一篇41项目优化 - 框架加载资源的项目, 本章要做的事情是按照框架的思想构建项目并完成怪物的自动巡逻状态,当主角靠近怪物时,怪物会朝向主角释放技能 首先新建脚本:BossCtrl.cs (通常把xxxCtrl.cs脚…...
【C++】模板进阶:深入解析模板特化
C语法相关知识点可以通过点击以下链接进行学习一起加油!命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与Queue 本章将…...
Python数据分析-世界上最富有的1000人
一、研究背景 随着全球化的加速发展和技术的进步,财富分配问题日益成为全球关注的焦点。财富的不平等现象日益明显,少数极富有的个人掌握了全球大部分的财富资源。了解全球最富有个人的财富分布及其背后的行业和国家因素,对于分析全球经济趋…...
CSS中隐藏滚动条的同时保留滚动功能
在CSS中,我们可以通过一些技巧来隐藏滚动条,同时保留滚动功能。以下是几种常用的方法和具体的实现步骤。 1. 使用 overflow 和 ::-webkit-scrollbar 这种方法适用于大多数现代浏览器。通过设置 overflow 属性启用滚动,同时利用 ::-webkit-s…...
我的标志:奇特的头像
<!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>与妖为邻</title><style>figu…...
中国空间计算产业链发展分析
2024中国空间计算产业链拆解 空间计算设备主要包括AR、VR、MR等终端设备。VR设备通常包括头戴式显示器(VR头盔)、手柄或追踪器等组件,用以完全封闭用户视野,营造虚拟环境体验。这些设备配备高分辨率显示屏、内置传感器和跟踪器。 …...
DAY14信息打点-JS 架构框架识别泄漏提取API 接口枚举FUZZ 爬虫插件项目
本课意义: 1.如何从表现中的JS提取价值信息 2.如何从地址中FUZZ提取未知的JS文件 3.如何从JS开放框架WebPack进行测试 一、JS 前端架构-识别&分析 在JS中寻找更多的URL地址,在JS代码逻辑(加密算法、APIKey配置、验证逻辑)中进…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
算法—栈系列
一:删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...
