Rust 学习笔记 - 流程控制 与 Range 类型

前言

任何一门编程语言几乎都脱离不了:变量、基本类型、函数、注释、循环、条件判断,这是一门编程语言的语法基础,只有当掌握这些基础语法及概念才能更好的学习 Rust。

条件判断

if 表达式

if 语句在其他语言中很常见,这里不再多做解释,看注释即可。

// 判断 n 是否小于 0
if n < 0 {// 当 n 小于 0 时执行这句print!("{} 是负数", n);
} else {// 否则执行这句print!("{} 是 0", n);
}

if 表达式也支持 if...else if...else 语句:

// 判断是否满足 if 条件1
if condition1 {// ...
} else if condition2 { // 当不满足 条件1 时,判断是否满足条件2// ...
} else { // 条件1 和 条件2 都不满足时// ...
}

在 Rust 中,没有像其他语言那样的三元表达式(三目运算符),但是在 Rust if 是一个表达式,这意味着可以在 let 语句中使用它来对变量进行条件赋值,从而达到类似三元表达式的效果。

let condition = true;// number 的类型必须明确,因此两个分支的返回值类型必须一致
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);

模式匹配(match 表达式)

虽然严格来说 match 并不是条件判断,但它常作为 Rust 的条件控制结构,其功能类似于其他语言中的 switch / case 语句。match 针对一个值执行模式匹配,并根据匹配到的模式执行相应的代码。

let value = some_val();match value {1 => println!("one"),2 => println!("two"),3 => println!("three"),_ => println!("anything"), // _ 类似于其他语言中的 default,用来匹配所有其它情况
}

match 匹配必须是穷尽的(exhaustive),也就是说所有可能的值都必须被考虑。使用 _ 模式可以捕捉所有未显式处理的值。

match 守卫(match guards)允许你为同一个 match 分支添加额外的条件判断,这样就可以基于值的属性做更精细的控制。

match some_val {val if val < 5 => println!("less than five"),val => println!("{}", val),
}

循环语句

loop 循环

loop 关键字创建了一个无限循环,它会不断地重复代码块,直到明确地通过 break 关键字退出循环。

let mut counter = 0;
loop {counter += 1;if counter == 10 {break;}
};

loop 也能返回一个值,这个值是在 break 后跟着的表达式。

let mut counter = 0;
let result = loop {counter += 1;if counter == 10 {break counter * 2; // 当 counter 达到 10 时退出循环,并返回 counter 的两倍}
};
println!("The result is {}", result); // 输出:The result is 20

while 循环

while 循环在循环的每次迭代开始前检查条件表达式,只有当条件为真时才会执行循环体。如果条件为假,则退出循环。

let mut number = 3;
while number != 0 {println!("{}", number);number -= 1;
}

和其他语言不一样在,Rust 中没有 do...while 语句,如果想要实现类似的效果可以通过 loop + if 模拟。

let mut count = 0;loop {count += 1;println!("这是第 {} 次迭代", count);// 判断条件,如果条件不满足,则退出循环if count >= 10 {break;}
}

for 循环

for 循环是开发中使用最频繁的循环,尤其是需要迭代一个序列或迭代器时。对于集合中的每个元素,它都会执行一次循环体。for 循环更加安全和高效,而且它不会产生越界的风险。

let a = [10, 20, 30, 40, 50];for element in a.iter() {println!("the value is: {}", element);
}

for 语句的特点

Rust 语言中的 for 循环不支持传统的 C/C++ 风格的 for (initialization; condition; update) 循环。在 Rust 中,for 循环被设计成基于迭代器的,这意味着它是用来遍历迭代器中的元素。之所以这样设计,是为了更安全和直接地处理集合中的元素,而不需要像在 C/C++ 中那样手动管理索引。

如果你想要执行类似于 for (int i = 0; i < 10; i++) 的循环,Rust 提供了一个 Range 类型,可以通过这个类型的 .. 或 ..=(包含上界)运算符来创建。

Rust 的 for 循环进行迭代示例如下:

// 使用 `..` 创建一个左闭右开的范围(0 到 9)
for i in 0..10 {println!("Value of i is: {}", i);
}// 使用 `..=` 创建一个闭区间的范围(0 到 10)
for i in 0..=10 {println!("Value of i is: {}", i);
}

注意:Range 类型产生的数值并不包括区间的上界,需要使用 ..= 语法才可以。当需要类似 C/C++ 风格的循环控制时,通常可以使用 Range 类型,这种方式也避免了因手动处理索引导致类似越界访问的错误。

Range 类型

在 Rust 中,Range 是一种迭代器类型,它生成一系列按顺序排列的数字。Range 通常用于 for 循环中,提供了一种简便的方式来执行重复操作一定次数的任务。

这里有两种最常用的 Range 类型:

  1. Range (start..end): 创建一个从 start 到 end(不包括)的迭代器,也就是左闭右开的区间。
  2. RangeInclusive (start..=end): 创建一个从 start 到 end(包括)的迭代器,闭区间,包含结束值。

创建 Range:

Range 通过使用两个点 .. 运算符来创建:

let a = 0..5; // 这将包括整数 0, 1, 2, 3, 4for i in a {println!("{}", i); // 打印 0 到 4。
}

创建 RangeInclusive:

RangeInclusive 通过使用三个点 ..= 运算符来创建:

let b = 0..=5; // 这将包括整数 0, 1, 2, 3, 4, 5for i in a {println!("{}", i); // 打印 0 到 5。
}

这两种类型都是迭代器,可以使用它们的 next 方法来逐个获取值,或者使用 for 循环来遍历这些值。

常用方法

Range 类型支持很多操作方法,下面列举几个常用的。

rev

rev 方法可以用来反转范围,创建一个新的迭代器,它会按照相反的顺序产生数值。

let range = (1..10).rev();
for num in range {println!("{num}"); // 将从 9 递减到 1
}
count

返回迭代器中剩余的元素数量。

let range_cnt = (1..100).count();
println!("{range_cnt}"); // 输出: 99
start_bound 和 end_bound

返回Range的起始边界和结束边界。返回的是一个Bound枚举,可以是Included(包含边界值)或Excluded(不包含边界值)。

let range = 1..100;
println!("{:?}", range.start_bound()); // 输出: Included(1)
println!("{:?}", range.end_bound());   // 输出: Excluded(100)
contains

判断一个指定的数值是否在Range内。如果是start..end类型的Range,会判断这个值是否大于等于start且小于end

let range = 1..100;
println!("{}", range.contains(&50));  // 输出: true
println!("{}", range.contains(&100)); // 输出: false
next

迭代Range并返回下一个值,如果迭代已经完成则返回None

let mut range = 1..3;
assert_eq!(range.next(), Some(1));
assert_eq!(range.next(), Some(2));
assert_eq!(range.next(), None);
last

返回Range中的最后一个数值,对 start..end 类型的Range来说,这个值是end - 1

let range = 1..100;
println!("{}", range.last().unwrap()); // 输出: 99
nth

获取迭代器中的第n个元素,并且将迭代器前进到此位置后面的元素。

let mut range = 1..100;
println!("{}", range.nth(49).unwrap()); // 输出: 50,即第50个元素
step_by

创建一个每n个数值产生一次的迭代器。

let range = (0..10).step_by(3);
for num in range {println!("{num}"); // 输出: 0, 3, 6, 9
}
其他

这个只列举了最常用的一些方法,Range 还支持很多其他的方法,此外,由于 Range 和 RangeInclusive 实现了 Iterator trait,因此提供了所有迭代器的标准方法,如 mapfilterfold, 和 collect 等。

结语

本章介绍了条件判断、循环语句以及 Range 类型,这是在程序开发中最常用的语句。在 Rust 中,不支持 do...whilefor ( i = 0; i <10; i++ )三元运算符 这类语法,但是可以用其他语法平替,这是从其他语言切换到 Rust 开发时需要注意的。

参考资料

  • Rust 圣经:https://doc.rust-lang.org/book/ch03-05-control-flow.html
  • Rust 实例:https://doc.rust-lang.org/rust-by-example/flow_control.html
  • Rust 标准库: https://doc.rust-lang.org/std/ops/struct.Range.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试经典150题【1-10】

文章目录 面试经典150题【1-10】88. 合并两个有序数组27.移除元素26.删除有序数组中的重复项80.删除有序数组中的重复项II169.多数元素189.轮转数组121.买卖股票的最佳时机1122. 买卖股票的最佳时机 II55.跳跃游戏![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ff…

nvm安装配置环境

前言 对于前端开发人员来说&#xff0c;多个项目可能用的不同的node版本&#xff0c;如何方便快速的转换版本&#xff0c;nvm版本管理工具的出现&#xff0c;解决这个问题。 实战 1. 搜索nvm版本&#xff0c;我用的1.1.2&#xff0c;下载后直接安装。 2.在d盘建立nvm空文件…

uniapp H5唤起手机App 中间下载页

我这里直接是打开中间下载页&#xff0c;在下载页判断手机是否已存在App&#xff0c;有则唤起App&#xff0c;没有则可点击下载按钮下载app。 唤起App的关键语句是&#xff1a;window.location.href scheme Scheme链接格式样式&#xff1a; [scheme]://[host]/[path]?[que…

蓝桥杯:C++队列、优先队列、链表

C普通队列 算法竞赛中一般用静态数组来模拟队列&#xff0c;或者使用STL queue。使用C的STL queue时&#xff0c;由于不用自己管理队列&#xff0c;因此代码很简洁。队列的部分操作如下。 C优先队列 很多算法需要用到一种特殊的队列&#xff1a;优先队列。它的特点是最优数据…

Android下SF合成流程重学习之onMessageInvalidate

Android下SF合成流程重学习之onMessageInvalidate 引言 虽然看了很多关于Android Graphics图形栈的文章和博客&#xff0c;但是都没有形成自己的知识点。每次学习了&#xff0c;仅仅是学习了而已&#xff0c;没有形成自己的知识体系&#xff0c;这次趁着有时间&#xff0c;这次…

pyhton在办公方面的应用

好久没发文了&#xff0c;转眼已经2024年了&#xff0c;我的电脑已经八岁了&#xff0c;近来状况频发&#xff0c;为防止它哪天突然嘎嘣&#xff0c;我多年搜集的资料付诸东流&#xff0c;故决定把资料备份一下这些代码有的是原创&#xff0c;有的是借鉴了其他博主的文章&#…

Python算法100例-1.7 最佳存款方案

完整源代码项目地址&#xff0c;关注博主私信’源代码’后可获取 1.问题描述2.问题分析3.算法设计4.完整的程序 1&#xff0e;问题描述 假设银行一年整存零取的月息为0.63%。现在某人手中有一笔钱&#xff0c;他打算在今后5年中的每年年底取出1000元&#xff0c;到第5年时刚…

民安智库如何做新品上市满意度调研

新品上市满意度调研是一种重要的市场研究方法&#xff0c;它通过收集和分析消费者对新产品的态度、购买意愿和满意度等方面的数据&#xff0c;帮助企业了解消费者的需求和期望&#xff0c;发现新产品的问题和不足&#xff0c;从而为产品改进提供有力的数据支持。下面将详细介绍…

什么是生产排产管理系统?哪个最好用?

阅读本文&#xff0c;你将了解&#xff1a;一、生产排产管理系统是什么&#xff1b;二、生产排产管理系统的功能&#xff1b;三、盘点五款好用的生产排产管理系统&#xff1b;四、生产排产管理系统的优势。 一、生产排产管理系统是什么 生产排产&#xff0c;也叫生产计划排程…

智能车竞赛详细介绍

一、引言 随着科技的飞速发展&#xff0c;智能车辆已成为当今研究的热点之一。智能车竞赛作为一项集科技、创新和竞技于一体的活动&#xff0c;为广大学子提供了一个展示才华、交流学习的平台。本文将对智能车竞赛进行详细介绍&#xff0c;包括竞赛背景、目标、赛程安排、技术…

【c++每天一题】跳跃游戏

题目 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1…

人机工程学和人机交互理论:智能座舱设计

hello家人们...本人熟悉PS、Xd、Ai、Sketch、Figma、墨刀、即时设计、mastergo、Pixso等行业设计软件以及前端开发等技能&#xff0c;拥有10年的UI经验&#xff0c;我们可以通过关注评论私信交流以帮助到您解决UI工作中的烦恼&#xff01;谢谢 人机工程学与人机交互理论&#x…

元宇宙专题:元宇宙概念娱乐应用场景案例研究报告 - 体验驱动篇

今天分享的是元宇宙系列深度研究报告&#xff1a;《元宇宙专题&#xff1a;元宇宙概念娱乐应用场景案例研究报告 - 体验驱动篇》。 &#xff08;报告出品方&#xff1a;艾瑞咨询&#xff09; 报告共计&#xff1a;51页 避免刻舟求剑地探索元宇宙概念产品 对于任何一个宏大而…

【Ubuntu内核】解决Ubuntu 20.04更新内核后无法联网的问题

最近在使用Ubuntu 20.04时&#xff0c;在更新内核后无法进行WiFi联网。我的电脑上装载的是AX211型号的无线网卡&#xff0c;之前安装了相应的驱动&#xff0c;并且一直正常使用。但不小心更新到了Linux 5.15.0-94-generic后&#xff0c;突然发现无法连接网络了。 于是首先怀疑…

【前端工程化面试题】什么是 CI/CD

CI/CD 是软件开发中的两个重要实践&#xff0c;分别代表持续集成&#xff08;Continuous Integration&#xff09;和持续交付/持续部署&#xff08;Continuous Delivery/Continuous Deployment&#xff09;。 持续集成 (Continuous Integration, CI)&#xff1a;持续集成是一种…

常见Web安全漏洞的实际案例和攻防技术

常见Web安全漏洞的实际案例和攻防技术 1、SQL注入攻击与防范: 通过一个简单的Web应用演示SQL注入攻击,包括入侵者如何通过输入恶意SQL语句来获取敏感数据。提供相应的防范措施,包括参数化查询、ORM框架的使用等,并附上实际代码演示。Copy code # 恶意SQL注入语句的示例 SEL…

练习接口测试第一步骤

最近一段时间学了Python语言&#xff0c;重新学了 Java&#xff0c;js&#xff0c;html语言&#xff0c;CSS&#xff0c;linux&#xff0c;一堆测试工具&#xff1b;唉&#xff5e; 在接触接口测试过程中补了很多课&#xff0c; 终于有点领悟接口测试的根本&#xff1b; 偶是…

firewall 常用命令

firewall 常用命令 重新装载 sudo firewall-cmd --reload 列出所有 sudo firewall-cmd --list-all 开启 masquerade 伪装IP firewall-cmd --permanent --add-masquerade 关闭 masquerade 伪装IP firewall-cmd --permanent --remove-masquerade

数据结构~二叉树(基础知识)

上一篇博客我们对树有了初步了解与学习&#xff0c;这篇我将初步学习二叉树&#xff01;&#xff01;&#xff08;新年快乐&#xff01;&#xff09; 目录 二叉树 1、定义&#xff1a; 2、特点&#xff1a; 3、基本形态&#xff1a; 4、二叉树的种类&#xff1a; &…

数据库系统概论整理与总结

数据库系统概论 第一章&#xff1a;绪论 四个基本概念 四个概念 数据&#xff1a;Data 数据库&#xff1a;DataBase 数据库管理系统:DBMS 数据库系统:DBS 打个比喻&#xff0c;比如说菜鸟物流&#xff1a; Data&#xff1a;快递 DB&#xff1a;物流厂库 DBMS&#xff1a;对…