Skip to content

控制流 ​

程序根据条件决定"做什么、做多少次"。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");
}

两条规则:

  1. 条件不需要括号(写了会有警告),但必须严格是 bool。if 1 { ... } 无法编译(expected bool, found integer)—— 不存在"非零即真"的隐式转换
  2. 分支的类型必须一致:每个分支产出同一类型的值

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); // 20

break counter * 2 把 20 交给了变量 result —— 计数器、重试逻辑这类"不知道要循环几次,但退出时想带走一个结果"的场景,就是它存在的意义。

continue 跳过本轮剩余代码,直接进入下一轮(while / for 中同样可用)。

3. while:条件循环 ​

每次循环前检查条件,条件不成立即结束:

rust
let mut n = 100;
while n > 0 {
    n -= 25;
}
println!("n={}", n); // 0

4. 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 ​

二者都用于干预循环的执行流程,区别在于"跳到哪":

breakcontinue
行为立即退出整个循环跳过本轮剩余语句,直接进入下一轮
位置之后的代码本轮及后续轮次都不执行本轮剩余不执行,后续轮次正常
典型用途找到目标即停止过滤掉不需要的轮次
携带值仅 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

三个细节:

  1. break 带值是 loop 独有的。while 和 for 的 break 不能跟值 —— 因为这两种循环整体求值结果是 (),没有值可以带出。这也是"不知道循环几次、退出时想带走结果"用 loop 而不是 while 的原因
  2. 嵌套循环中,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 指定作用于哪一层。

  1. 在 for 遍历集合时优先考虑能否用迭代器方法(filter、find 等)替代 continue/break 手写逻辑 —— 闭包与迭代器课程会展开。

参考 ​