控制流(Control Flow)
控制流(Control Flow)结构允许你控制代码的执行路径。Rust 提供了几种控制流结构,包括 if
表达式和循环。
if 表达式
if
表达式允许根据条件分支代码:
fn main() {
let number = 3;
if number < 5 {
println!("条件为真");
} else {
println!("条件为假");
}
}
多重条件
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 整除");
}
}
在 let 语句中使用 if
因为 if
是一个表达式,我们可以在 let
语句的右侧使用它:
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("number 的值是: {number}");
}
注意:if
的每个分支必须返回相同类型的值:
fn main() {
let condition = true;
// 这会编译错误,因为类型不匹配
// let number = if condition { 5 } else { "six" };
// 正确的做法
let number = if condition { 5 } else { 6 };
println!("number: {}", number);
}
循环
Rust 有三种循环:loop
、while
和 for
。
loop 循环
loop
关键字告诉 Rust 一遍又一遍地执行一段代码直到你明确要求停止:
fn main() {
let mut counter = 0;
loop {
counter += 1;
if counter == 10 {
break;
}
println!("计数: {}", counter);
}
println!("循环结束!");
}
从循环返回值
可以在 break
表达式之后添加你想要返回的值:
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("结果是: {result}");
}
循环标签
当存在嵌套循环时,break
和 continue
应用于此时最内层的循环。你可以选择在一个循环上指定一个循环标签:
fn main() {
let mut count = 0;
'counting_up: loop {
println!("count = {count}");
let mut remaining = 10;
loop {
println!("remaining = {remaining}");
if remaining == 9 {
break;
}
if count == 2 {
break 'counting_up;
}
remaining -= 1;
}
count += 1;
}
println!("End count = {count}");
}
while 条件循环
while
循环在条件为真时执行:
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
for 循环
for
循环是最常用的循环结构,用于遍历集合:
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a {
println!("值是: {element}");
}
}
使用范围的 for 循环
fn main() {
// 正向计数
for number in 1..4 {
println!("{}!", number);
}
// 包含结束值
for number in 1..=3 {
println!("包含结束值: {}", number);
}
// 反向计数
for number in (1..4).rev() {
println!("倒数: {}!", number);
}
println!("LIFTOFF!!!");
}
match 表达式
match
允许将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码:
fn main() {
let number = 13;
match number {
1 => println!("一"),
2 | 3 | 5 | 7 | 11 => println!("这是一个质数"),
13..=19 => println!("十几"),
_ => println!("其他数字"),
}
}
匹配 Option
fn main() {
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;
match some_number {
Some(i) => println!("匹配到数字: {}", i),
None => println!("没有数字"),
}
// 使用 if let 简化
if let Some(value) = some_string {
println!("匹配到字符串: {}", value);
}
}
匹配守卫
fn main() {
let num = Some(4);
match num {
Some(x) if x < 5 => println!("小于五: {}", x),
Some(x) => println!("{}", x),
None => (),
}
}
if let 语法糖
当你只关心一个特定的匹配情况时,if let
提供了更简洁的语法:
fn main() {
let config_max = Some(3u8);
// 使用 match
match config_max {
Some(max) => println!("最大值是 {}", max),
_ => (),
}
// 使用 if let(更简洁)
if let Some(max) = config_max {
println!("最大值是 {}", max);
}
}
while let 循环
类似于 if let
,while let
只要模式匹配就一直进行 while
循环:
fn main() {
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
while let Some(top) = stack.pop() {
println!("{}", top);
}
}
最佳实践
- 优先使用
for
循环:遍历集合时比while
更安全 - 使用
if let
简化单一匹配:当只关心一种情况时 - 合理使用
match
:处理多种情况时比if-else
更清晰 - 避免无限循环:确保
loop
有明确的退出条件
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
// 好的做法:使用 for 循环
for (index, value) in numbers.iter().enumerate() {
println!("索引 {} 的值是 {}", index, value);
}
// 使用 match 处理 Result
let result = "42".parse::<i32>();
match result {
Ok(num) => println!("解析成功: {}", num),
Err(e) => println!("解析失败: {}", e),
}
}