跳到主要内容

控制流(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 有三种循环:loopwhilefor

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}");
}

循环标签

当存在嵌套循环时,breakcontinue 应用于此时最内层的循环。你可以选择在一个循环上指定一个循环标签

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 letwhile 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);
}
}

最佳实践

  1. 优先使用 for 循环:遍历集合时比 while 更安全
  2. 使用 if let 简化单一匹配:当只关心一种情况时
  3. 合理使用 match:处理多种情况时比 if-else 更清晰
  4. 避免无限循环:确保 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),
}
}