基础语法 beginner 30 分钟 更新 2026-06-15

控制流

使用 if、loop、while 和 for 表达程序分支与重复。

控制流

你会学到什么

  • if 是表达式,可以产生值。
  • loop 可以用 break value 返回值。
  • for 是遍历集合和 range 的常用方式。

最小示例

let level = if score >= 60 { "通过" } else { "继续练习" };

for chapter in 1..=3 {
    println!("第 {chapter} 章");
}

运行代码

cd examples
cargo run -p rt_05_control_flow
cargo test -p rt_05_control_flow

代码讲解

if 的两个分支必须返回同一种类型:

let status = if score >= 60 { "pass" } else { "retry" };

for 常用于遍历 range、array、slice、Vec 和任何实现了 IntoIterator 的类型。

loop 适合表达“直到满足条件才退出”的逻辑:

let mut value = 0;
let result = loop {
    value += 1;
    if value == 3 {
        break value * 10;
    }
};

常见错误

Rust 不会把数字自动当成布尔值:

let count = 1;
if count {
    println!("has value");
}

修复方式是写出明确条件:

if count > 0 {
    println!("has value");
}

练习

  • 写一个函数,根据分数返回 "A""B""C""D"
  • for 计算 1..=100 的和。

小结

Rust 的控制流强调类型一致和条件明确。分支和循环都可以参与表达式求值。

下一步

下一阶段会进入 Rust 最核心的主题:所有权、借用和生命周期。

完整示例代码

下面是 examples/05_control_flow/ 的完整源码。无需 clone 仓库,直接在页面上阅读、复制、对照运行。

examples/05_control_flow/src/main.rs
fn score_grade(score: u32) -> &'static str {
    if score >= 90 {
        "A"
    } else if score >= 80 {
        "B"
    } else if score >= 70 {
        "C"
    } else {
        "D"
    }
}

fn sum_to(limit: u32) -> u32 {
    let mut total = 0;
    for value in 1..=limit {
        total += value;
    }
    total
}

fn countdown(start: u32) -> Vec<u32> {
    let mut values = Vec::new();
    let mut current = start;
    while current > 0 {
        values.push(current);
        current -= 1;
    }
    values
}

fn count_until(target: u32) -> u32 {
    let mut count = 0;
    loop {
        count += 1;
        if count == target {
            break count;
        }
    }
}

fn main() {
    println!("score 92 => {}", score_grade(92));
    println!("sum 1..=5 => {}", sum_to(5));
    println!("countdown: {:?}", countdown(3));
    println!("loop result: {}", count_until(4));
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn grades_scores() {
        assert_eq!(score_grade(92), "A");
        assert_eq!(score_grade(82), "B");
        assert_eq!(score_grade(70), "C");
        assert_eq!(score_grade(60), "D");
    }

    #[test]
    fn sums_range() {
        assert_eq!(sum_to(5), 15);
    }

    #[test]
    fn creates_countdown() {
        assert_eq!(countdown(3), vec![3, 2, 1]);
    }

    #[test]
    fn loop_returns_value() {
        assert_eq!(count_until(4), 4);
    }
}
examples/05_control_flow/Cargo.toml
[package]
name = "rt_05_control_flow"
version.workspace = true
edition.workspace = true
publish.workspace = true