概述

控制流是编程语言的核心功能之一,它决定了代码的执行顺序。Rust 提供了丰富的控制流结构,包括条件判断、循环和模式匹配。

if 表达式

基本 if 语句

fn main() {
    let number = 6;
    
    if number < 5 {
        println!("条件为真,number 小于 5");
    } else {
        println!("条件为假,number 大于或等于 5");
    }
}

if else if 链

fn main() {
    let number = 6;
    
    if number % 4 == 0 {
        println!("number 能被 4 整除");
    } else if number % 3 == 0 {
        println!("number 能被 3 整除");
    } else if number % 2 == 0 {
        println!("number 能被 2 整除");
    } else {
        println!("number 不能被 4、3 或 2 整除");
    }
}

if 作为表达式

fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };
    
    println!("number 的值是: {}", number);
    
    // 注意:if 表达式的两个分支必须返回相同类型
    // let number = if condition { 5 } else { "six" };  // 错误!
}

在 let 语句中使用 if

fn main() {
    let number = 7;
    
    let result = if number % 2 == 0 {
        "偶数"
    } else {
        "奇数"
    };
    
    println!("{} 是 {}", number, result);
}

loop 循环

无限循环

fn main() {
    let mut count = 0;
    
    loop {
        println!("count = {}", count);
        count += 1;
        
        if count == 5 {
            break;  // 跳出循环
        }
    }
    
    println!("循环结束");
}

从循环返回值

fn main() {
    let mut counter = 0;
    
    let result = loop {
        counter += 1;
        
        if counter == 10 {
            break counter * 2;  // 返回值
        }
    };
    
    println!("结果是: {}", result);
}

循环标签

fn main() {
    let mut count = 0;
    
    'counting_up: loop {
        println!("count = {}", count);
        let mut remaining = 10;
        
        loop {
            println!("remaining = {}", remaining);
            
            if remaining == 9 {
                break;  // 跳出内层循环
            }
            
            if count == 2 {
                break 'counting_up;  // 跳出外层循环
            }
            
            remaining -= 1;
        }
        
        count += 1;
    }
    
    println!("最终 count = {}", count);
}

while 循环

基本 while 循环

fn main() {
    let mut number = 3;
    
    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }
    
    println!("LIFTOFF!!!");
}

使用 while 遍历数组

fn main() {
    let a = [10, 20, 30, 40, 50];
    let mut index = 0;
    
    while index < 5 {
        println!("a[{}] = {}", index, a[index]);
        index += 1;
    }
}

for 循环

遍历集合

fn main() {
    let a = [10, 20, 30, 40, 50];
    
    for element in a.iter() {
        println!("值是: {}", element);
    }
}

使用范围

fn main() {
    for number in 1..4 {
        println!("{}!", number);
    }
    println!("LIFTOFF!!!");
}

反向范围

fn main() {
    for number in (1..4).rev() {
        println!("{}!", number);
    }
    println!("LIFTOFF!!!");
}

遍历范围并获取索引

fn main() {
    let fruits = ["苹果", "香蕉", "橙子"];
    
    for (index, fruit) in fruits.iter().enumerate() {
        println!("水果 {}: {}", index + 1, fruit);
    }
}

使用 for 循环遍历数组(推荐)

fn main() {
    let a = [10, 20, 30, 40, 50];
    
    for element in a.iter() {
        println!("值是: {}", element);
    }
    
    // 或者直接使用引用
    for element in &a {
        println!("值是: {}", element);
    }
    
    // 可变遍历
    let mut a = [10, 20, 30, 40, 50];
    for element in &mut a {
        *element *= 2;
    }
    println!("修改后的数组: {:?}", a);
}

match 表达式

match 是 Rust 中强大的控制流结构,类似于其他语言中的 switch 语句,但更强大。

基本 match

fn main() {
    let number = 3;
    
    match number {
        1 => println!("一"),
        2 => println!("二"),
        3 => println!("三"),
        4 => println!("四"),
        5 => println!("五"),
        _ => println!("其他数字"),
    }
}

匹配 Option

fn main() {
    let some_number = Some(5);
    let some_string = Some("字符串");
    let absent_number: Option<i32> = None;
    
    if let Some(i) = some_number {
        println!("some_number 包含的值是: {}", i);
    }
    
    if let Some(s) = some_string {
        println!("some_string 包含的值是: {}", s);
    }
    
    if let None = absent_number {
        println!("absent_number 没有值");
    }
}

匹配多个模式

fn main() {
    let number = 5;
    
    match number {
        1 | 2 => println!("1 或 2"),
        3..=5 => println!("3 到 5 之间"),
        _ => println!("其他数字"),
    }
}

匹配守卫

fn main() {
    let number = 4;
    let pair = (2, -2);
    
    match number {
        n if n % 2 == 0 => println!("{} 是偶数", n),
        n => println!("{} 是奇数", n),
    }
    
    match pair {
        (x, y) if x == -y => println!("{} 和 {} 互为相反数", x, y),
        _ => println!("其他情况"),
    }
}

绑定值

fn main() {
    let age = 18;
    
    match age {
        0 => println!("婴儿"),
        n @ 1..=12 => println!("儿童,年龄: {}", n),
        n @ 13..=19 => println!("青少年,年龄: {}", n),
        n => println!("成年人,年龄: {}", n),
    }
}

@ 绑定

fn main() {
    let age = 25;
    
    match age {
        n @ 0..=12 => println!("儿童: {}", n),
        n @ 13..=19 => println!("青少年: {}", n),
        n @ 20..=59 => println!("成年人: {}", n),
        n => println!("老年人: {}", n),
    }
}

if let 和 while let

if let 简化模式匹配

fn main() {
    let some_value = Some(5);
    
    // 使用 match
    match some_value {
        Some(x) => println!("值是: {}", x),
        _ => println!("没有值"),
    }
    
    // 使用 if let(更简洁)
    if let Some(x) = some_value {
        println!("值是: {}", x);
    }
    
    // if let 可以包含 else
    if let Some(x) = some_value {
        println!("值是: {}", x);
    } else {
        println!("没有值");
    }
}

while let 处理迭代

fn main() {
    let mut optional = Some(0);
    
    while let Some(i) = optional {
        if i > 5 {
            println!("大于 5,退出");
            optional = None;
        } else {
            println!("i 是 {:?},尝试 again", i);
            optional = Some(i + 1);
        }
    }
}

break 和 continue

break 跳出循环

fn main() {
    let mut count = 0;
    
    loop {
        count += 1;
        
        if count == 10 {
            println!("达到 10,退出");
            break;
        }
    }
    
    println!("最终 count: {}", count);
}

continue 跳过本次迭代

fn main() {
    for number in 1..=10 {
        if number % 2 == 0 {
            continue;  // 跳过偶数
        }
        println!("奇数: {}", number);
    }
}

break 和 continue 与标签

fn main() {
    'outer: for x in 0..10 {
        for y in 0..10 {
            if x == 2 && y == 2 {
                println!("在 ({}, {}) 处跳出", x, y);
                break 'outer;
            }
            println!("({}, {})", x, y);
        }
    }
}

实际应用示例

计算斐波那契数列

fn main() {
    let n = 10;
    let mut fib = vec![0, 1];
    
    for i in 2..n {
        let next = fib[i - 1] + fib[i - 2];
        fib.push(next);
    }
    
    println!("斐波那契数列前 {} 项: {:?}", n, &fib[..n]);
}

猜数字游戏

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("猜数字游戏!");
    
    let secret_number = rand::thread_rng().gen_range(1..=100);
    
    loop {
        println!("请输入你的猜测:");
        
        let mut guess = String::new();
        io::stdin()
            .read_line(&mut guess)
            .expect("无法读取输入");
        
        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("请输入一个有效的数字!");
                continue;
            }
        };
        
        println!("你猜测的数字: {}", guess);
        
        match guess.cmp(&secret_number) {
            Ordering::Less => println!("太小了!"),
            Ordering::Greater => println!("太大了!"),
            Ordering::Equal => {
                println!("你赢了!");
                break;
            }
        }
    }
}

温度转换器

fn main() {
    let temperatures = [0, 20, 37, 100];
    
    println!("摄氏度\t华氏度");
    println!("------\t------");
    
    for celsius in temperatures.iter() {
        let fahrenheit = celsius * 9 / 5 + 32;
        println!("{}\t{}", celsius, fahrenheit);
    }
}

总结

本教程详细介绍了 Rust 的控制流结构:

  1. if 表达式

    • 基本 if 语句
    • if else if 链
    • if 作为表达式
    • 在 let 语句中使用 if
  2. 循环

    • loop:无限循环,可以返回值
    • while:条件循环
    • for:遍历集合和范围
    • 循环标签:控制嵌套循环
  3. match 表达式

    • 基本 match
    • 匹配 Option
    • 匹配多个模式
    • 匹配守卫
    • 绑定值
  4. if let 和 while let

    • 简化模式匹配
    • 处理迭代
  5. break 和 continue

    • 跳出循环
    • 跳过本次迭代
    • 与标签配合使用

下一步

在下一教程中,我们将学习 Rust 的核心概念——所有权与借用,这是 Rust 最独特和最重要的特性之一。我们将了解:

  • 所有权规则

  • 借用与引用

  • 生命周期

  • 智能指针

继续学习 Rust,深入理解这门语言的精髓!