2.5 控制流:条件语句与循环
控制流是编程语言的核心,它决定了程序执行的路径和顺序。Rust 提供了多种控制流结构,包括条件语句和循环,这些结构既强大又安全,能够帮助你编写清晰、高效的代码。
2.5.1 条件语句:if 表达式
在 Rust 中,if 是一个表达式,这意味着它可以返回一个值,并用于赋值或作为其他表达式的一部分。这与许多语言中 if 只是语句不同。
基本语法:
fn main() {
let number = 6;
if number % 4 == 0 {
println!("数字可以被4整除");
} else if number % 3 == 0 {
println!("数字可以被3整除");
} else if number % 2 == 0 {
println!("数字可以被2整除");
} else {
println!("数字不能被4、3或2整除");
}
}
关键点:
条件必须是
bool类型:Rust 不会自动将非布尔类型转换为布尔值。这意味着你不能像在某些语言中那样写if number { ... },除非number本身就是bool类型。let number = 3; // if number { // 错误!期望 bool,找到了整数 // println!("数字非零"); // } if number != 0 { println!("数字非零"); }if作为表达式使用:因为if是表达式,我们可以将其结果赋值给一个变量。所有分支必须返回相同类型的值。let condition = true; let number = if condition { 5 } else { 6 }; println!("number 的值是: {}", number);注意:如果分支返回不同类型,编译器会报错。例如,
if condition { 5 } else { "six" }会失败,因为5是整数,而"six"是字符串。
2.5.2 循环:loop、while 和 for
Rust 提供了三种循环:loop、while 和 for。
1. loop 无限循环
loop 关键字用于创建一个无限循环,除非显式地使用 break 语句退出。
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // 退出循环并返回值
}
};
println!("result 的值为: {}", result); // 输出: result 的值为: 20
}
关键点:
loop可以像if一样,通过break后跟一个表达式来返回值。- 这在需要重复执行某个操作直到满足条件,并需要返回最终结果时非常有用。
2. while 条件循环
while 循环在每次迭代前检查一个条件,只有当条件为 true 时才执行循环体。
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("发射!");
}
关键点:
while循环适合在循环次数不确定,但有一个明确的终止条件时使用。- 与
if一样,while的条件也必须是bool类型。
3. for 遍历集合
for 循环是 Rust 中最常用、最强大的循环结构。它用于遍历一个集合(如数组、向量、范围等)中的每个元素。
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("元素的值为: {}", element);
}
// 使用 Range 进行循环
for number in (1..4).rev() { // .rev() 反转范围
println!("{}!", number);
}
println!("发射!");
}
关键点:
- 安全性:
for循环比while循环更安全,因为它自动处理集合的边界检查,避免了索引越界的风险。 - 简洁性:
for循环的语法简洁,易于阅读和理解。 - 范围(Range):
1..4表示一个从 1 到 3(不包括 4)的范围。1..=4表示从 1 到 4(包括 4)的范围。 iter()方法:for循环通常与iter()方法一起使用,它返回集合中元素的不可变引用。如果需要修改元素,可以使用iter_mut()。
2.5.3 循环控制:break 和 continue
break:立即退出当前循环。continue:跳过当前迭代的剩余代码,立即开始下一次迭代。
fn main() {
for number in 1..10 {
if number == 5 {
continue; // 跳过 number 为 5 的情况
}
if number == 8 {
break; // 在 number 为 8 时退出循环
}
println!("{}", number);
}
// 输出: 1, 2, 3, 4, 6, 7
}
2.5.4 循环标签:处理嵌套循环
当有嵌套循环时,break 和 continue 默认作用于最内层的循环。如果你想控制外层循环,可以使用循环标签。
fn main() {
let mut count = 0;
'outer: loop {
println!("外层循环: count = {}", count);
let mut remaining = 10;
loop {
println!("内层循环: remaining = {}", remaining);
if remaining == 9 {
break; // 只退出内层循环
}
if count == 2 {
break 'outer; // 退出外层循环
}
remaining -= 1;
}
count += 1;
}
println!("结束循环,count = {}", count);
}
关键点:
- 标签以单引号开头(
'outer),后面跟一个冒号('outer:)。 - 通过
break 'label或continue 'label来指定要控制哪个循环。
总结
Rust 的控制流结构设计得既强大又安全:
if是表达式,可以返回值,但所有分支类型必须一致。loop用于无限循环,可以返回值。while用于条件循环。for是遍历集合的首选,安全且简洁。break和continue用于控制循环流程。- 循环标签 用于在嵌套循环中精确控制外层循环。
掌握这些控制流结构,是编写复杂 Rust 程序的基础。它们不仅帮助你实现逻辑,还通过编译期的检查,避免了常见的编程错误,如索引越界或类型不匹配。
