控制流
Rust 的控制流主要分为 条件判断 和 循环 两大类,它们允许你根据不同的条件执行不同的代码块,或者重复执行某段代码直到满足特定条件。
| 分类 | 类型 | 说明 |
|---|---|---|
| 条件判断 | if | 根据条件执行不同的代码分支 |
else if | 多重条件判断 | |
else | 条件不满足时的默认分支 | |
| 循环 | loop | 无限循环,需用 break 退出 |
while | 条件满足时循环 | |
for | 迭代集合中的元素 |
条件判断
if 表达式
语法: if condition { ... } else { ... }
if 表达式允许根据条件执行不同的代码分支。你提供一个条件并表示 "如果条件满足,运行这段代码;如果条件不满足,不运行这段代码."
条件必须是一个布尔表达式,即 true 或 false。编译器不会进行隐式类型转换,因此你不能直接使用数字或其他类型作为条件。
fn main() {
let number = 3;
if number 5 { // 错误: 条件必须是一个布尔表达式,不能直接使用数字
if number < 5 { // 正确: 条件是一个布尔表达式,判断 number 是否小于 5
println!("condition was true"); // 如果小于 5,输出 "condition was true"
} else {
println!("condition was false"); // 否则,输出 "condition was false"
}
}else if 分支
语法: if condition1 { ... } else if condition2 { ... } else { ... }
逐个匹配条件,一旦找到满足条件的分支,其他分支将被忽略。
可以将 else if 表达式与 if 和 else 组合来实现多重条件。
fn main() {
let number = 6;
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}在 let 语句中使用 if
语法: let variable = if condition { value1 } else { value2 };
if 表达式可以直接在 let 语句中使用,这样你就可以根据条件来决定变量的值。
if 的各个分支可能产生的结果值都必须是相同类型;否则编译器会报错。
fn main() {
let condition = true;
// 如果 condition 为 true,number 的值为 5;否则为 6
let number = if condition { 5 } else { 6 };
// 输出 "The value of number is: 5"
println!("The value of number is: {number}");
}循环
Rust 有三种循环: loop、while 和 for 循环。
loop 循环
语法: loop { ... }
loop 循环会一直执行,直到你显式地使用 break 语句来退出循环。
fn main() {
loop {
println!("again!"); // 这段代码会无限循环,输出 "again!"
// break; // 使用 break 语句退出循环
}
}使用快捷键
Ctrl-C来中断一个陷入无限循环的程序
从循环返回值
语法: let variable = loop { ... break value; ... };
loop 循环可以返回一个值,这个值是通过 break 语句指定的。
fn main() {
let mut counter = 0;
let result = loop {
counter += 1; // 每次循环将 counter 增加 1
if counter == 10 {
// 当 counter 等于 10 时,使用 break 返回 counter 的两倍
break counter * 2;
}
};
println!("The result is {result}"); // 输出 "The result is 20"
}跳过循环
语法: continue;
continue 语句会跳过当前循环的剩余代码,直接进入下一次循环。
fn main() {
let mut count = 0;
loop {
count += 1; // 每次循环将 count 增加 1
if count == 3 {
// 当 count 等于 3 时,跳过当前循环的剩余代码,直接进入下一次循环
continue;
}
println!("count = {count}"); // 输出当前的 count 值
if count == 5 {
// 当 count 等于 5 时,使用 break 语句退出循环
break;
}
}
}while 循环
语法: while condition { ... }
while 循环会一直执行,直到指定的条件不满足为止。
fn main() {
let mut number = 3;
while number != 0 { // 当 number 不等于 0 时,继续循环
println!("{number}!"); // 输出当前的 number 值
number -= 1; // 每次循环将 number 减少 1
}
println!("LIFTOFF!!!"); // 当循环结束时,输出 "LIFTOFF!!!"
}跳出和跳过
while 循环也支持 break 和 continue 语句,用法与 loop 循环相同。
跳出语法: break;
跳过语法: continue;
fn main() {
let mut number = 3;
while number != 0 {
number -= 1; // 每次循环将 number 减少 1
// 当 number 等于 2 时,跳过当前循环的剩余代码,直接进入下一次循环
if number == 2 {
continue;
}
// 当 number 等于 1 时,使用 break 语句退出循环
if number == 1 {
break;
}
println!("{number}!"); // 输出当前的 number 值
}
println!("LIFTOFF!!!"); // 当循环结束时,输出 "LIFTOFF!!!"
}while let 表达式
语法: while let pattern = expression { ... }
while let 表达式允许你在循环中同时进行模式匹配和条件判断。
fn main() {
let mut stack = Vec::new();
stack.push(1); // 将 1 压入栈
stack.push(2); // 将 2 压入栈
stack.push(3); // 将 3 压入栈
// 当 stack 不为空时,将栈顶元素弹出并赋值给 top
while let Some(top) = stack.pop() {
println!("{top}"); // 输出当前的 top 值
}
}
// 输出:
// 3
// 2
// 1for 循环
语法: for variable in collection { ... }
for 循环用于迭代集合中的元素。Rust 提供了多种方式来创建迭代器。
fn main() {
let a = [10, 20, 30, 40, 50];
// 迭代数组 a 中的每个元素,并将当前元素的值赋给变量 element
for element in a {
println!("the value is: {element}"); // 输出当前的元素值
}
}使用 Range 迭代
Rust 提供了一个 Range 语法来生成一个数字序列,这在需要迭代一定范围内的数字时非常有用。
语法:
| 语法 | 说明 |
|---|---|
(start..end) | 生成一个从 start 到 end - 1 的范围 |
(start..=end) | 生成一个从 start 到 end 的范围 |
(start..end).rev() | 生成一个从 end - 1 到 start 的范围,并使用 rev() 方法反转顺序 |
fn main() {
// 迭代从 1 到 3 的数字,并使用 rev() 方法反转顺序
for number in (1..4).rev() {
println!("{number}!"); // 输出当前的 number 值
}
println!("LIFTOFF!!!"); // 当循环结束时,输出 "LIFTOFF!!!"
}
// 输出:
// 3!
// 2!
// 1!
// LIFTOFF!!!标签 label
可以为loop结构、while结构、for结构指定标签,break和continue都可以指定标签来确定要跳出哪一个层次的循环结构。不仅如此,任何一个独立的{}语句块都可以加上标签,并使用break来提前退出标签。
嵌套 loop 中使用标签
语法: 'label_name: loop { ... }
fn main() {
'outer: loop {
println!("Entered outer loop");
for i in 0..3 {
if i == 1 {
break 'outer; // 直接跳出外层 loop,而不仅仅是内层 for 循环
}
println!(" i = {}", i);
}
}
println!("Exited outer loop");
}嵌套 while 中使用标签
语法: 'label_name: while condition { ... }
fn main() {
let mut x = 0;
'outer: while x < 5 {
let mut y = 0;
while y < 3 {
if x == 2 && y == 1 {
break 'outer; // 跳出外层 while 循环
}
println!("x = {}, y = {}", x, y);
y += 1;
}
x += 1;
}
}嵌套 for 中使用标签
语法: 'label_name: for variable in collection { ... }
fn main() {
'outer: for i in 0..3 {
for j in 0..3 {
if i == 1 && j == 1 {
break 'outer; // 跳出外层 for 循环
}
println!("i = {}, j = {}", i, j);
}
}
}标签块中使用 break 返回值
语法: break 'label_name value;
fn main() {
let result = 'block: {
for i in 0..5 {
if i == 3 {
break 'block 42; // 从标签块中返回值 42
}
}
100 // 默认返回值
};
println!("Result: {}", result); // 输出: Result: 42
}标签块中使用 continue 跳过
语法: continue 'label_name;
fn main() {
'outer: for i in 0..3 {
for j in 0..3 {
if j == 1 {
continue 'outer; // 跳过外层循环的当前迭代,继续下一次外层迭代
}
println!("i = {}, j = {}", i, j);
}
}
}