控制流
约 915 字大约 3 分钟
2025-09-26
1. if 表达式
if 表达式允许根据条件执行不同的代码分支
重要
- 条件必须是 bool 值
if条件不需要圆括号,但每个分支体都要用花括号包起来;缺少else时默认返回()
基本使用
fn main() {
let number = 3;
if number < 5 {
println!("condition was true");
} else if number > 1 {
println!("condition was true too");
} else {
println!("condition was false");
}
}1.1 if let
当只关心某个匹配分支时,可用 if let 简化,未命中的分支会被直接忽略。
if let
fn main() {
let config = Some(3u8);
if let Some(max) = config {
println!("max is {max}");
}
}1.2 if 赋值
当只关心根据条件生成一个值时,可用 let variable if condition 简化
注
let if 的每个分支的可能返回值类型必须是相同类型
let if 语句的使用
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {number}");
}2. while 循环
while 会在每次迭代前判断条件,条件为 false 时退出
注
语义等价于手写 loop { if !cond { break; } ... }
while 循环
fn main() {
let mut n = 3;
while n > 0 {
println!("{n}");
n -= 1;
}
println!("lift off!");
}while let 搭配模式匹配常用于按值迭代直到耗尽。
while let
fn main() {
let mut stack = vec![1, 2, 3];
while let Some(top) = stack.pop() {
println!("pop {top}");
}
}3. loop 循环
loop 循环是无限循环,本身不会退出,通常搭配 break 与 continue 关键字使用
注
break 可以从循环中返回值
loop 循环与 break 和 continue
fn main() {
let mut n = 0;
let doubled = loop {
n += 1;
if n == 3 {
continue;
}
if n == 5 {
break n * 2;
}
println!("n = {n}");
};
println!("doubled = {doubled}");
}3.1 嵌套循环
在嵌套循环中通常会给目标循环命名一个标签 (使用 'name 的形式) 这样再结合 break 和 continue 就能精确控制要跳出的层级
重要
break 和 continue 默认作用于最内层循环
嵌套循环
fn main() {
let mut counter = 0;
'counting_up: loop {
println!("count = {counter}");
let mut remaining = 10;
loop {
println!("remaining = {}", remaining);
if remaining == 9 {
break;
}
if counter == 2 {
break 'counting_up;
}
remaining -= 1;
}
counter += 1;
}
println!("End count = {counter}");
}4. for 循环
for 用于遍历迭代器,语法糖会自动对迭代目标调用 .into_iter()。遍历数值范围用 start..end或 start..=end
注
调用 .into_iter() 指的是: 编译器会把 target 移动进编译器生成的迭代器中,然后再循环。循环结束所有权也将被消耗。这样做的好处:
- 统一遍历入口(任何实现
IntoIterator的类型都能用for) - 自动遵守所有权语义(
into_iter移动,iter借用,iter_mut可变借用) - 由迭代器负责边界检查和优化(减少手写索引、减少越界风险)
等价的 while 循环:
let mut iter = target.into_iter(); // while 循环需要手动 .into_iter()
while let Some(x) = iter.next() {}基本使用
fn main() {
// 1,2,3
for n in 1..4 {
println!("{n}");
}
// 3,2,1
for n in (1..=3).rev() {
println!("{n}");
}
}变更所有权的 for 循环
fn main() {
let mut v = vec![10, 20, 30];
// 不消耗所有权 等价于 target.iter()
for x in &v {
println!("ref {x}");
}
// 可变借用,原地修改 等价于 target.iter_mut()
for x in &mut v {
*x += 1;
}
// 移动所有权,v 不再可用
for x in v {
println!("owned {x}");
}
}