控制流
程序根据条件决定"做什么、做多少次"。Rust 的控制流有三种构造:if 分支、loop / while / for 循环。它们的共同特点是:都是表达式。你在猜数字游戏里已经用过 loop 和 match,本课系统化并补上两个独特机制。
1. if 表达式
rust
let n = 7;
if n < 0 {
println!("negative");
} else if n == 0 {
println!("zero");
} else {
println!("positive");
}两条规则:
- 条件不需要括号(写了会有警告),但必须严格是
bool。if 1 { ... }无法编译(expectedbool, found integer)—— 不存在"非零即真"的隐式转换 - 分支的类型必须一致:每个分支产出同一类型的值
if 是表达式,因此可以直接赋值,或作为函数的尾表达式:
rust
let score = 85;
let level = if score >= 90 {
"优秀"
} else if score >= 60 {
"及格"
} else {
"不及格"
};
println!("level={}", level); // 及格
// 条件必须是 bool:`if 1 { ... }` 会编译失败(expected `bool`, found integer)这与你在 0005 练习里用 match 作返回值是同一个思路 —— match 就是分支更丰富的 if。
2. loop:可以通过 break 返回值的无限循环
loop 专门表达"故意无限循环",配合 break 退出。Rust 的独特之处:break 可以携带一个值,作为整个 loop 表达式的结果:
rust
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // 把 20 交给 result
}
};
println!("result={}", result); // 20break counter * 2 把 20 交给了变量 result —— 计数器、重试逻辑这类"不知道要循环几次,但退出时想带走一个结果"的场景,就是它存在的意义。
continue 跳过本轮剩余代码,直接进入下一轮(while / for 中同样可用)。
3. while:条件循环
每次循环前检查条件,条件不成立即结束:
rust
let mut n = 100;
while n > 0 {
n -= 25;
}
println!("n={}", n); // 04. for 与 Range:遍历的首选
遍历集合或区间时,for 是首选 —— 不会像手写 while + 索引那样越界:
rust
for n in 1..=3 {
print!("{} ", n); // 1 2 3(..= 包含两端)
}
for n in (1..=3).rev() {
print!("{} ", n); // 3 2 1:rev() 倒序
}rust
for n in 1..=3 {
print!("{} ", n); // 1 2 3(..= 包含两端)
}
println!();
for n in (1..=3).rev() {
print!("{} ", n); // 3 2 1
}
println!();两种区间:0..3 不含右端(半开区间,你在 0003 的 for _i in 0..3 用过);1..=100 包含两端(猜数字的 random_range(1..=100) 同款语法)。
5. break 与 continue
二者都用于干预循环的执行流程,区别在于"跳到哪":
break | continue | |
|---|---|---|
| 行为 | 立即退出整个循环 | 跳过本轮剩余语句,直接进入下一轮 |
| 位置之后的代码 | 本轮及后续轮次都不执行 | 本轮剩余不执行,后续轮次正常 |
| 典型用途 | 找到目标即停止 | 过滤掉不需要的轮次 |
| 携带值 | 仅 loop 支持(break 表达式) | 不支持 |
rust
// continue:跳过本轮剩余语句,直接进入下一轮 —— 只打印奇数
for n in 1..=6 {
if n % 2 == 0 {
continue;
}
print!("{} ", n); // 1 3 5
}
println!();
// break:立即退出整个循环,后面的轮次不再执行
let mut n = 0;
loop {
n += 1;
if n == 3 {
break;
}
}
println!("n={}", n); // 3三个细节:
break带值是loop独有的。while和for的break不能跟值 —— 因为这两种循环整体求值结果是(),没有值可以带出。这也是"不知道循环几次、退出时想带走结果"用loop而不是while的原因- 嵌套循环中,
break/continue只作用于最内层。要直接退出外层循环,给循环贴标签:
rust
'outer: for x in 1..=3 {
for y in 1..=3 {
if x * y > 4 {
break 'outer; // 退出的是外层循环
}
println!("x={x}, y={y}");
}
}'outer 是循环标签(单引号开头),break 'outer / continue 'outer 指定作用于哪一层。
- 在
for遍历集合时优先考虑能否用迭代器方法(filter、find等)替代continue/break手写逻辑 —— 闭包与迭代器课程会展开。
参考
- 关键字速查 ——
if/loop/while/for/break/continue/in