Rust 控制流

程序的本质就是"做判断、重复干活、根据情况分流"。这一篇讲 Rust 的控制流:if 分支、loop/while/for 循环、以及强大的 match。Rust 控制流的一个重要特点是它们大多是表达式,有返回值——这是 Rust 的标志性设计。

1. if 表达式

Rust 的 if 和其他语言类似,但有几个细节:

fn main() {
    let score = 85;

    // if 表达式(条件必须是 bool,不能 0/1 隐式转换)
    if score >= 90 {
        println!("优秀");
    } else if score >= 60 {
        println!("及格");
    } else {
        println!("不及格");
    }

    // if 是表达式,有返回值!可以赋给变量
    let status = if score >= 60 { "通过" } else { "挂科" };
    println!("{}", status);     // 通过

    // 两个分支的类型必须相同
    // let x = if cond { 1 } else { "two" };   // 编译错误!
}

关键点:

2. loop 无限循环

loop 是无条件循环,类似其他语言的 while true。它配合 break 跳出:

fn main() {
    // loop:无条件无限循环(类似 while true)
    let mut count = 0;
    loop {
        count += 1;
        if count >= 5 {
            break;          // 跳出循环
        }
    }
    println!("count = {}", count);     // 5

    // loop 也是表达式,break 可以带返回值
    let mut n = 0;
    let result = loop {
        n += 1;
        if n == 10 {
            break n * 2;    // 返回 20
        }
    };
    println!("result = {}", result);

    // 嵌套循环用 label(标签)精确控制 break 哪一层
    let mut found = false;
    'outer: for i in 1..=3 {
        for j in 1..=3 {
            if i * j == 6 {
                println!("找到 {} * {}", i, j);
                found = true;
                break 'outer;    // 跳出外层循环
            }
        }
    }
}

loop 的几个亮点:

3. while 条件循环

while 在条件为真时循环,为假时停止。用法和其他语言一样:

fn main() {
    // while:条件循环,条件为 false 时停止
    let mut n = 3;
    while n > 0 {
        println!("{}!", n);
        n -= 1;
    }
    println!("发射!");

    // 用 while 遍历集合(不如 for 优雅)
    let arr = [10, 20, 30];
    let mut i = 0;
    while i < arr.len() {
        println!("arr[{}] = {}", i, arr[i]);
        i += 1;
    }
    // 实际几乎不用 while 遍历,用 for 更地道
}

虽然可以用 while 遍历集合,但Rust 推荐用 for——更简洁,不会越界,也更能表达"遍历每个元素"的意图。

4. for 循环(最常用)

Rust 的 for 不是 C 风格的 for(init;cond;inc),而是迭代器风格——遍历任何"可迭代"的对象。这是 Rust 最常用的循环形式:

fn main() {
    // for:Rust 最常用的循环(没有 C 风格的 for(init;cond;inc))
    // 通过迭代器实现

    // 遍历范围
    for i in 0..5 {
        print!("{} ", i);       // 0 1 2 3 4
    }
    println!();

    for i in 1..=3 {
        print!("{} ", i);       // 1 2 3
    }
    println!();

    // 遍历数组
    let nums = [10, 20, 30, 40];
    for n in nums {
        print!("{} ", n);       // 10 20 30 40
    }
    println!();

    // 需要索引:用 .iter().enumerate()
    for (i, val) in nums.iter().enumerate() {
        println!("索引 {}: 值 {}", i, val);
    }

    // 反向遍历
    for n in (1..4).rev() {
        print!("{} ", n);       // 3 2 1
    }
    println!();

    // 步长(用 step_by)
    for n in (0..10).step_by(2) {
        print!("{} ", n);       // 0 2 4 6 8
    }
}

几个亮点:

5. match 模式匹配(初识)

match 是 Rust 最强大的控制流,后面有专门一篇讲枚举和模式匹配。这里先看它的基本用法:

fn main() {
    // match:Rust 最强的控制流,模式匹配
    // 必须穷尽所有可能(_ 表示其他)
    let num = 3;
    match num {
        1 => println!("一"),
        2 | 3 => println!("二或三"),       // | 表示或
        4..=9 => println!("四到九"),       // 范围模式
        _ => println!("其他"),
    }

    // match 也是表达式,有返回值
    let day = 3;
    let name = match day {
        1 => "周一",
        2 => "周二",
        3 => "周三",
        4 => "周四",
        5 => "周五",
        _ => "周末",
    };
    println!("今天是{}", name);

    // match 必须穷尽!漏写一个分支会编译报错
    // 这是 Rust 比 switch 安全的地方:不会"漏处理"
}

match 的几个重要特性:

6. break 和 continue

这两个是循环控制关键字,和其他语言一致:

fn main() {
    // break:跳出循环
    // continue:跳过本次,进入下一次

    for n in 1..=10 {
        if n % 2 == 0 {
            continue;       // 跳过偶数
        }
        if n > 7 {
            break;          // 大于 7 就停
        }
        println!("{}", n);  // 输出 1 3 5 7
    }

    // 在 loop 里用 break 返回值
    let mut sum = 0;
    let total = loop {
        sum += 1;
        if sum >= 100 {
            break sum;      // 返回 100
        }
    };
    println!("total = {}", total);
}

7. if let 简写

当你只关心 match 的一种情况时,可以用 if let 简写。这是 match 的语法糖,代码更简洁。具体例子在枚举篇会看到:

8. Rust 没有 switch

Rust 没有 C/Java 的 switch 语句——因为 match 完全覆盖了 switch 的功能,而且更强大、更安全(强制穷尽、不会忘记 break、支持复杂模式)。习惯之后,你会发现 match 比 switch 优雅太多。

9. 控制流都是表达式

这是 Rust 反复强调的特点:if、loop、while、for、match 都是表达式,都返回值(可能是 unit ())。这意味着你可以:

这种"表达式优先"的设计让 Rust 代码更紧凑,也鼓励函数式风格。

小结

这一篇你掌握了 Rust 的全部控制流:if/else(条件必须是 bool)、loop(无限循环,可返回值)、while、for(迭代器风格,最常用)、match(模式匹配,必须穷尽)。最重要的两个特点:都是表达式(有返回值)、match 比 switch 强大(强制穷尽)。下一篇讲函数——Rust 的函数有几个独特细节,比如"尾表达式即返回值"。

← 上一篇 Rust 运算符

下一篇 Rust 函数

✈️💬