【Rust自学】3.6. 控制流:循环

3.6.0. 写在正文之前

欢迎来到Rust自学的第三章,一共有6个小节,分别是:

  • 变量与可变性
  • 数据类型:标量类型
  • 数据类型:复合类型
  • 函数和注释
  • 控制流:if else
  • 控制流:循环(本文)

通过第二章的小游戏(没看的初学者强烈建议看一下),相信你已经学会了基本的Rust语法,而在第三章我们将更深一层,了解Rust中的通用的编程概念。

喜欢的话记得点赞、收藏加关注哦,想要跟着学下去记得关注专栏哦

3.6.1. Rust的循环

Rust一共提供了三种循环:

  • loop
  • while
  • for

3.6.2. loop循环

loop关键字告诉Rust要反复执行一段代码,除非喊停。以下是一个例子,它会不断打印6657 up up!

rust 复制代码
fn main(){
	loop {
		println!("6657 up up!");
	}
}

可以在loop循环中使用break关键字来告诉程序何时停止

rust 复制代码
fn main(){
	let mut counter = 0;
	let result = loop {
		counter += 1;

		if counter == 10 {
			break counter * 2;
		}
	};
	println!("The result is:{}", result);
}

代码逻辑描述:

  • counter 初始化为 0,在每次循环中递增 1。
  • 当 counter 等于 10 时,break 退出循环,同时返回 counter * 2(即 20)。
  • loop 是一个表达式,其返回值是 break 的返回值,因此可以直接赋值给 result。
  • result 最终打印出 20。

代码特点:

  • Rust 的 loop 是表达式,可以直接绑定结果到变量。
  • break 可以携带返回值(这里是 counter * 2),并作为 loop 的结果。
  • let 语句要求赋值表达式后需要加分号(;),因此 loop 的结束大括号 } 后需加分号。

3.6.3. while条件循环

while循环在每次执行循环体之前都要判断一次条件

rust 复制代码
fn main() {
    let mut countdown = 10; // 倒计时从10开始

    println!("Rocket Launch Countdown:");

    while countdown > 0 {
        println!("T-minus {}...", countdown);
        countdown -= 1; // 每次减少1
    }

    println!("🚀 Liftoff!");
    println!("Huston, we have a problem.");
}

这是一个简单的while循环示例代码,其运行结果是:

复制代码
Rocket Launch Countdown:
T-minus 10...
T-minus 9...
T-minus 8...
T-minus 7...
T-minus 6...
T-minus 5...
T-minus 4...
T-minus 3...
T-minus 2...
T-minus 1...
🚀 Liftoff!
Huston, we have a problem

3.6.4. 使用for循环遍历集合

当然也可以使用whileloop来遍历集合,但是易错且低效

这是个使用while的例子:

rust 复制代码
fn main() {
    let numbers = [10, 20, 30, 40, 50];
    let mut index = 0;

    println!("Using while loop:");
    while index < 5 {
        println!("Number at index {}: {}", index, numbers[index]);
        index += 1;
    }
}

使用while时极有可能造成索引越界触发panic!,而且运行速度较慢,因为每次都要检查index < 5这个条件。

这是个使用for的例子(实现同样的效果):

rust 复制代码
fn main() {
    let numbers = [10, 20, 30, 40, 50];

    println!("Using for loop:");
    for (index, number) in numbers.iter().enumerate() {
        println!("Number at index {}: {}", index, number);
    }
}

1. numbers.iter()

  • 调用集合 numbers.iter() 方法,创建一个不可变的迭代器,用于逐个访问集合中的元素。在 Rust 中,for 循环并不直接操作集合,而是操作实现了 Iterator 特征的迭代器。.iter() 是 Vec(或其他集合)常用的方法,生成一个指向集合元素的引用的迭代器。使用for循环简洁紧凑,它可以针对集合中的每个元素来执行代码。由于for循环的安全性、简洁性,所以它在Rust中使用最多

2. .enumerate()

• 为迭代器的每个元素附加一个索引。索引从 0 开始,是一个usize类型的值。.enumerate() 将迭代器的每个元素包装成 (index, value) 的形式,其中:index 是元素在集合中的索引。value 是当前迭代器指向的元素。.enumerate() 返回一个新的迭代器,迭代出的元素类型是 (usize, &T),其中 T 是集合中元素的类型。在这里,numbers 是一个Vec<i32>,因此&T&i32

3. for (index, number) in ...

• for 循环支持解构元组,(index, number) 表示我们直接将 enumerate() 提供的 (usize, &T)元组解构成两个变量:index:当前元素的索引。number:当前元素的引用(不可变)。

假设 numbers[10, 20, 30, 40, 50],执行时的过程如下:

  1. 调用 numbers.iter() 创建迭代器。
  2. 调用 .enumerate(),生成 (索引, 元素引用) 的迭代器
  3. for 循环解构出索引和元素:
    • 第一次循环:index = 0, number = &10
    • 第二次循环:index = 1, number = &20
    • 第三次循环:index = 2, number = &30
    • ...
  4. 打印 indexnumber,输出每个元素的索引和值。

由于使用for循环呢的安全、简洁性,所以它在Rust里使用最多。

3.6.5. Range

Range由标准库提供。用户可以通过Range生成它们之间的数字(不含结束)。使用rev方法可以反转Range

rust 复制代码
fn main() {
    println!("Rocket Launch Countdown:");

    for countdown in (1..=10).rev() {
        println!("T-minus {}...", countdown);
    }

    println!("🚀 Liftoff!");
    println!("Huston, we have a problem.");
}

这个例子使用for循环、Rangerev实现了上文while函数所实现的火箭倒数

代码解析

  1. (1...=10):
    • 这是一个 Range,表示从 1 到 10(包含 10)。
    • ...= 是包含上限的范围操作符。
  2. .rev():
    • 反转迭代器,生成一个从 10 到 1 的递减序列。
相关推荐
王德博客7 分钟前
【Java课堂笔记】Java 入门基础语法与面向对象三大特性详解
java·开发语言
菜鸟谢16 分钟前
windows xp 下载 sp0 sp1 sp2 sp3 sp4
后端
AirMan18 分钟前
你真的懂 MySQL 的一致性读和当前读的区别吗?
后端·面试
David爱编程24 分钟前
容器性能优化实战指南——防止“吃爆”服务器就靠这些招!
后端·docker·容器
wkj00125 分钟前
接口实现类向上转型和向上转型解析
java·开发语言·c#
Android洋芋27 分钟前
GitHub项目部署的终极指南:从零到一掌握Docker实战
后端
林太白44 分钟前
Next.js超简洁完整篇
前端·后端·react.js
前端付豪44 分钟前
汇丰登录风控体系拆解:一次 FaceID 被模拟攻击的调查纪实
前端·后端·架构
寒士obj1 小时前
类加载的过程
java·开发语言
无名之逆1 小时前
大三自学笔记:探索Hyperlane框架的心路历程
java·开发语言·前端·spring boot·后端·rust·编程