RUST教程: while循环20例
介绍
在学习编程语言时,掌握循环结构是至关重要的。在RUST编程语言中,while循环是一种非常强大而灵活的工具,它允许我们重复执行特定的代码块,直到满足某个条件为止。在本文中,我们将深入探讨RUST中的while循环,并提供20个实例来帮助您更好地理解和运用它。
示例1:打印数字
让我们从一个简单的例子开始。假设我们想要打印从1到10的数字。我们可以使用while循环来实现这个目标。首先,我们定义一个变量count并将其初始化为1。然后,我们使用while循环来判断count是否小于等于10。如果是,我们将打印出当前的数字,并将count加1。这个过程将一直重复,直到count大于10为止。
// 定义一个名为main的函数,这是Cargo.toml文件中的入口点
fn main() {
// 声明一个名为count的可变整数变量,并初始化为1
let mut count = 1;
// 开始一个循环,条件是count的值小于或等于10
while count <= 10 {
// 使用println!宏打印格式化的字符串和count的值,字符串"Number: {}"中的{}会被count的值替换
println!("Number: {}", count);
// 将count的值增加1
count += 1;
}
}
这个代码的运行结果是打印出从1到10的所有整数,每个数字前面都会有"Number: "的标识。具体来说,输出如下:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Number: 6
Number: 7
Number: 8
Number: 9
Number: 10
这是因为代码中的 while 循环会一直执行,直到 count 的值大于10为止。在循环体内,首先会打印出 count 的值,然后将 count 的值增加1。这样,循环会一直进行下去,直到 count 的值超过10,循环才会结束。
示例2:求和
除了打印数字,我们还可以使用while循环来计算一系列数字的和。让我们看一个示例。在这个例子中,我们使用while循环来计算从1到100的所有数字的和。我们初始化了两个变量sum和count,并通过每次循环将count的值加到sum上,然后将count增加1。最后,我们打印出计算得到的和。
// 定义一个名为main的函数,这是Cargo.toml文件中的入口点
// 定义一个名为main的函数,这是Cargo.toml文件中的入口点
fn main() {
// 声明一个名为sum的可变整数变量,并初始化为0
let mut sum = 0;
// 声明一个名为count的可变整数变量,并初始化为1
let mut count = 1;
// 开始一个循环,条件是count的值小于或等于100
while count <= 100 {
// 将count的值加到sum上
sum += count;
// 将count的值增加1
count += 1;
}
// 使用println!宏打印格式化的字符串和sum的值,字符串"Sum: {}"中的{}会被sum的值替换
println!("Sum: {}", sum);
}
这个代码的运行结果是:Sum: 5050。
解释:这个代码通过一个while循环,从1开始逐个累加计数器的值到sum变量中,直到计数器的值大于100为止。最后,打印出sum的值,即1到100的所有整数的和,其值为5050。
示例3:猜数字游戏
除了在数值上使用while循环,我们还可以在游戏中使用它。让我们看一个简单的猜数字游戏的例子。在这个例子中,我们使用while循环来实现一个猜数字游戏。游戏的规则是,玩家需要猜一个秘密数字,如果猜对了,游戏结束,否则根据猜测的数字给出相应的提示。循环会一直执行,直到玩家猜对为止。
// 引入 std::io 库,该库提供了处理 I/O 操作的功能
use std::io;
// 定义 main 函数,程序的入口点
fn main() {
// 声明并初始化一个名为 secret_number 的变量,其值为 42
let secret_number = 42;
// 打印 "Guess the number!",提示用户猜测数字
println!("Guess the number!");
// 开始一个无限循环,除非遇到 break 语句才会退出循环
loop {
// 提示用户输入猜测的数字
println!("Please input your guess:");
// 声明并初始化一个名为 guess 的可变长字符串,初始值为空字符串
let mut guess = String::new();
// 从标准输入读取一行数据并存放到 guess 中,如果读取失败会抛出异常并传递给 expect 方法,expect 方法会返回一个错误,错误信息为 "Failed to read line"
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
// 将 guess 字符串解析为无符号的32位整数,并赋值给 guess 变量,如果解析失败会返回一个错误,错误信息为 "Failed to parse string to integer",这种情况下会执行 Err 下面的代码块,继续循环并提示用户重新输入
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
// 如果用户猜测的数字等于 secret_number,打印 "Congratulations! You guessed the number!" 并退出循环
if guess == secret_number {
println!("Congratulations! You guessed the number!");
break;
// 如果用户猜测的数字小于 secret_number,打印 "Too small! Try again." 并继续循环
} else if guess < secret_number {
println!("Too small! Try again.");
// 如果用户猜测的数字大于 secret_number,打印 "Too big! Try again." 并继续循环
} else {
println!("Too big! Try again.");
}
}
}
这段代码实现了一个简单的猜数字游戏。首先声明了一个变量 secret_number,其值为42。然后进入一个无限循环,提示用户输入猜测的数字。用户的输入会被解析为无符号的32位整数并和 secret_number 进行比较。如果猜测正确,程序会打印祝贺信息并退出循环;如果猜测的数字小于 secret_number,程序会提示 "Too small! Try again.";如果猜测的数字大于 secret_number,程序会提示 "Too big! Try again."。
示例4:遍历数组
在RUST中,我们可以使用while循环来遍历一个数组。让我们看一个示例:
// 定义一个名为 main 的函数,它是 Rust 程序的入口点。
fn main() {
// 创建一个名为 numbers 的数组,包含五个元素:1, 2, 3, 4, 5。
let numbers = [1, 2, 3, 4, 5];
// 声明一个名为 index 的变量,并初始化为0,它将被用来跟踪数组中的当前元素。
let mut index = 0;
// 使用 while 循环遍历 numbers 数组,条件是 index 小于 numbers 的长度(即数组的元素数量)。
while index < numbers.len() {
// 使用 println! 宏打印当前索引指向的数组元素的值,并在末尾添加换行符。
println!("Number: {}", numbers[index]);
// 将 index 增加1,以便在下一次循环迭代中检查下一个数组元素。
index += 1;
}
}
运行这段代码后,你会在控制台看到以下输出:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
在这个例子中,我们定义了一个包含一些数字的数组numbers。然后,我们使用while循环来遍历数组,并打印出每个数字。我们使用一个变量index来跟踪当前遍历到的数组元素的索引。
示例5:处理用户输入的命令
在编写交互式程序时,我们经常需要处理用户输入的命令。使用while循环,我们可以不断接收并处理用户的命令,直到用户选择退出。让我们看一个简单的示例:
// 引入 std::io 库,这个库提供了处理 I/O 操作的功能,比如读取用户输入
use std::io;
// 定义 main 函数,这是程序的入口点
fn main() {
// 创建一个可变的 String 对象,用于存储用户输入的命令,初始值为空字符串
let mut input = String::new();
// 当用户输入的命令(去除前后空格后)不是 "quit" 时,执行循环内的代码
while input.trim() != "quit" {
// 打印提示信息,让用户输入一个命令(或者输入 'quit' 退出程序)
println!("Please enter a command (or 'quit' to exit):");
// 清空 input 变量,准备接收新的用户输入
input.clear();
// 从标准输入读取一行数据并存放到 input 中,如果读取失败会抛出异常并传递给 expect 方法,expect 方法会返回一个错误,错误信息为 "Failed to read line"
io::stdin().read_line(&mut input)
.expect("Failed to read line");
// 在这里处理用户输入的命令,这里只是简单地打印出用户输入的命令
// Process the command here
println!("Command: {}", input);
}
}
这个程序会不断地提示用户输入一个命令,直到用户输入了 “quit”。每次用户输入一个命令,它都会打印出这个命令(不包括 “quit”)。这个程序通过标准输入(通常是键盘)获取命令,并使用标准输出(通常是屏幕)显示结果。
在这个例子中,我们使用while循环来接收用户输入的命令。循环会一直执行,直到用户输入的命令是"quit"为止。在每次循环中,我们清空输入字符串并读取用户的输入。然后,我们可以在循环内部处理用户的命令,这里我们只是简单地将其打印出来。
示例6:模拟角色移动
在游戏开发中,我们经常需要模拟角色的移动。使用while循环,我们可以在游戏中实现角色移动的逻辑。让我们看一个简单的示例:
// 定义一个名为 main 的函数,它是 Rust 程序的入口点。
fn main() {
// 声明一个名为 position 的变量并初始化为0,这个变量是一个可变的整数。
let mut position = 0;
// 创建一个 while 循环,条件是 position 的值小于10。循环体内的代码块将会持续执行,直到 position 的值不再小于10。
while position < 10 {
// 使用 println! 宏打印出一条信息,显示当前 position 的值。
println!("Current position: {}", position);
// 将 position 的值增加1。
position += 1;
}
}
这段代码的主要功能是:在 while 循环中,首先打印出当前 position 的值,然后将 position 的值增加1。这个循环会一直进行,直到 position 的值达到或超过10为止。因此,这段代码的输出将是 position 从0到9的每个值。
在这个例子中,我们定义了一个变量position来表示角色在游戏中的位置。然后,我们使用while循环来模拟角色的移动。循环会一直执行,直到角色的位置达到10为止。在每次循环中,我们打印出当前的位置,并将位置增加1。
示例7:处理文件中的数据
在实际的应用程序中,我们经常需要处理文件中的数据。使用while循环,我们可以逐行读取文件,并对每一行的数据进行处理。让我们看一个简单的示例:
// 引入 std::fs::File,用于文件操作
use std::fs::File;
// 引入 std::io::{self, BufRead},用于文件读取和缓冲读取
use std::io::{self, BufRead};
// 引入 std::path::Path,用于文件路径操作
use std::path::Path;
// 定义 main 函数,程序的入口点
fn main() {
// 使用 if let 语句来处理 read_lines 函数的返回结果。read_lines 函数尝试打开 "data.txt" 文件并读取所有行。
if let Ok(lines) = read_lines("data.txt") {
// 对于每一行,进行处理
for line in lines {
// 再次使用 if let 语句处理每一行的读取结果
if let Ok(data) = line {
// 打印每一行的内容
println!("{}", data);
}
}
} else {
// 如果读取文件失败,打印错误信息
println!("Failed to read file");
}
}
// 定义一个函数 read_lines,参数为一个文件名,返回一个 io::Result<io::Lines<io::BufReader<File>>>,这是一个读取器,用于逐行读取文件内容。
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
// 打开指定的文件,如果出现错误则返回错误,否则继续执行下一行代码。
let file = File::open(filename)?;
// 使用 BufReader 来创建一个新的读取器,它可以从 file 中读取数据,并且可以一次读取多行。然后将这个读取器包装成 Ok 类型的结果。
Ok(io::BufReader::new(file).lines())
}
以上就是这段代码的逐行注释。这段代码的主要功能是打开名为 "data.txt" 的文件,并打印出该文件的所有内容。如果打开文件失败,会打印出 "Failed to read file"。
在这个例子中,我们定义了一个函数read_lines,它接收一个文件名作为参数,并返回一个io::Lines迭代器。然后,我们使用while循环来逐行读取文件中的数据,并打印出每一行的内容。这个示例展示了如何处理文件中的数据,并利用while循环来进行逐行处理。
示例8:验证用户的输入
在开发应用程序时,我们经常需要验证用户的输入是否符合要求。使用while循环,我们可以持续要求用户输入,直到输入满足预期的条件。让我们看一个简单的示例:
// 引入 std::io,标准输入/输出库,用于读取用户输入等操作
use std::io;
// 定义 main 函数,程序的入口点
fn main() {
// 声明一个名为 valid_input 的变量并初始化为 false,表示当前输入是否有效
let mut valid_input = false;
// 创建一个 while 循环,条件是 valid_input 为 false(即输入无效)
while !valid_input {
// 打印提示信息,要求用户输入一个正数
println!("Please enter a positive number:");
// 声明一个名为 input 的变量并初始化为空字符串,用于存储用户输入的数据
let mut input = String::new();
// 从标准输入(通常是键盘)读取一行数据并存放到 input 中,如果读取失败会抛出异常并传递给 expect 方法,expect 方法会返回一个错误,错误信息为 "Failed to read line"
io::stdin().read_line(&mut input)
.expect("Failed to read line");
// 使用 parse 方法尝试将 input 解析为 i32 类型的数字,并使用 match 语句处理结果
let number: i32 = match input.trim().parse() {
// 如果解析成功,将解析的数字赋值给 number 变量
Ok(num) => num,
// 如果解析失败,继续循环,不执行任何操作
Err(_) => continue,
};
// 检查数字是否大于0,如果是,设置 valid_input 为 true,跳出循环
if number > 0 {
valid_input = true;
}
}
// 打印 "Valid input received!" 表示收到了有效的输入
println!("Valid input received!");
}
此代码的功能是持续提示用户输入一个正数,直到用户确实输入了一个正数才会停止并输出“Valid input received!”。如果用户输入的不是正数,程序会忽略这个输入并提示用户重新输入。
在这个例子中,我们使用while循环来验证用户的输入是否为正数。循环会一直执行,直到用户输入的是一个正数为止。在每次循环中,我们读取用户的输入,并将其转换为整数。如果转换成功,并且输入的数值大于0,我们将设置valid_input为true,循环结束。否则,循环会继续执行,要求用户重新输入。
示例9:实现复杂算法
通过使用while循环,我们可以实现各种复杂的算法和逻辑。让我们看一个简单的示例,使用while循环来计算斐波那契数列的前n个数字:
这段代码是用Rust语言编写的,它打印出斐波那契数列的前10个数字。下面是对每一行的详细注释:
fn main() { // 定义主函数,程序的入口点
let n = 10; // 声明一个变量 n 并初始化为10,表示要打印的斐波那契数列的项数
let mut fib = (0, 1); // 声明一个可变变量 fib 并初始化为 (0, 1),即斐波那契数列的前两项
while n > 0 { // 当 n 大于 0 时,执行循环体
println!("{}", fib.0); // 打印 fib 的第一项(在Rust中,元组的索引从0开始)
fib = (fib.1, fib.0 + fib.1); // 更新 fib,将其第二项和第一项的和作为新的第一项,原来的第三项作为新的第二项
n -= 1; // 将 n 减 1,即将 n 更新为 n-1
}
}
因此,这个程序会打印出斐波那契数列的前10个数字:0, 1, 1, 2, 3, 5, 8, 13, 21, 34。
在这个例子中,我们定义了一个变量n来表示要计算的斐波那契数列的前n个数字。然后,我们使用while循环来计算并打印出每个斐波那契数。我们使用一个元组(a, b)来保存计算过程中的中间结果,其中a表示当前的斐波那契数,b表示下一个斐波那契数。在每次循环中,我们更新元组的值,并将n减1,直到n为0为止。