【Rust】循环控制结构

Rust 提供了多种循环控制结构,包括 loopwhilefor 以及相关的控制语句。这些结构在 Rust 中都是表达式,可以返回值。

1. loop 循环

基本语法

loop 创建一个无限循环,必须显式使用 break 退出。

rust 复制代码
fn main() {
    let mut counter = 0;
    
    loop {
        println!("循环次数: {}", counter);
        counter += 1;
        
        if counter >= 5 {
            break; // 退出循环
        }
    }
}

loop 返回值

loop 是表达式,可以通过 break 返回值。

rust 复制代码
fn main() {
    let mut counter = 0;
    
    let result = loop {
        counter += 1;
        
        if counter == 10 {
            break counter * 2; // 返回 20
        }
    };
    
    println!("结果是: {}", result); // 输出: 20
}

嵌套循环和标签

rust 复制代码
fn main() {
    let mut count = 0;
    
    'outer: loop {
        println!("进入外层循环,count = {}", count);
        let mut inner = 0;
        
        'inner: loop {
            println!("  内层循环,inner = {}", inner);
            inner += 1;
            
            if inner >= 3 {
                break 'inner; // 跳出内层循环
            }
        }
        
        count += 1;
        if count >= 2 {
            break 'outer; // 跳出外层循环
        }
    }
    
    println!("循环结束");
}

2. while 循环

基本语法

while 在条件为真时执行循环。

rust 复制代码
fn main() {
    let mut number = 3;
    
    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }
    
    println!("发射!");
}

while let 模式匹配

while let 在模式匹配成功时继续循环。

rust 复制代码
fn main() {
    let mut stack = Vec::new();
    
    // 压入数据
    stack.push(1);
    stack.push(2);
    stack.push(3);
    stack.push(4);
    
    // 弹出数据直到栈为空
    while let Some(top) = stack.pop() {
        println!("弹出: {}", top);
    }
    
    println!("栈已空");
    
    // 另一个例子:处理Option
    let mut values = vec![Some(1), Some(2), None, Some(3)];
    
    while let Some(Some(value)) = values.pop() {
        println!("处理值: {}", value);
    }
}

复杂条件的 while

rust 复制代码
fn main() {
    let mut x = 0;
    let mut y = 10;
    
    // 复合条件
    while x < 5 && y > 5 {
        println!("x = {}, y = {}", x, y);
        x += 1;
        y -= 1;
    }
    
    // 使用函数作为条件
    fn should_continue(count: i32) -> bool {
        count < 10
    }
    
    let mut count = 0;
    while should_continue(count) {
        println!("计数: {}", count);
        count += 1;
    }
}

3. for 循环

遍历集合

Rust 的 for 循环主要用于遍历迭代器。

rust 复制代码
fn main() {
    // 遍历数组
    let arr = [10, 20, 30, 40, 50];
    
    for element in arr.iter() {
        println!("元素: {}", element);
    }
    
    // 简化写法(数组会隐式转换为迭代器)
    for element in arr {
        println!("简化写法: {}", element);
    }
    
    // 遍历切片
    let slice = &arr[1..4]; // [20, 30, 40]
    for element in slice {
        println!("切片元素: {}", element);
    }
}

范围迭代

使用范围表达式进行迭代。

rust 复制代码
fn main() {
    // 正向范围 (包含)
    for number in 1..=5 { // 1, 2, 3, 4, 5
        println!("正向: {}", number);
    }
    
    // 正向范围 (不包含)
    for number in 1..5 { // 1, 2, 3, 4
        println!("正向不包含: {}", number);
    }
    
    // 反向迭代
    for number in (1..5).rev() { // 4, 3, 2, 1
        println!("反向: {}", number);
    }
    
    // 步长迭代
    for number in (0..10).step_by(2) { // 0, 2, 4, 6, 8
        println!("步长2: {}", number);
    }
}

遍历向量

rust 复制代码
fn main() {
    let v = vec![10, 20, 30];
    
    // 获取值(所有权)
    for value in v {
        println!("值: {}", value);
    }
    // 注意:这里 v 的所有权已被移动
    
    let v2 = vec![40, 50, 60];
    
    // 获取引用(不获取所有权)
    for value in &v2 {
        println!("引用值: {}", value);
    }
    // v2 仍然可用
    println!("向量长度: {}", v2.len());
    
    // 获取可变引用
    let mut v3 = vec![1, 2, 3];
    for value in &mut v3 {
        *value *= 2; // 修改值
    }
    println!("修改后: {:?}", v3); // [2, 4, 6]
}

遍历 HashMap

rust 复制代码
use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();
    scores.insert("Alice", 90);
    scores.insert("Bob", 85);
    scores.insert("Charlie", 95);
    
    // 遍历键值对
    for (name, score) in &scores {
        println!("{}: {}", name, score);
    }
    
    // 只遍历键
    for name in scores.keys() {
        println!("学生: {}", name);
    }
    
    // 只遍历值
    for score in scores.values() {
        println!("分数: {}", score);
    }
    
    // 遍历并修改值
    let mut mutable_scores = HashMap::new();
    mutable_scores.insert("Alice", 90);
    
    for score in mutable_scores.values_mut() {
        *score += 5;
    }
    println!("加分后: {:?}", mutable_scores);
}

4. 循环控制语句

breakcontinue

rust 复制代码
fn main() {
    // break 示例
    let mut count = 0;
    
    loop {
        count += 1;
        
        if count == 3 {
            println!("遇到 3,跳过");
            continue; // 跳过本次循环剩余部分
        }
        
        if count == 5 {
            println!("遇到 5,终止循环");
            break; // 终止循环
        }
        
        println!("当前计数: {}", count);
    }
    
    // 带值的 break
    let result = loop {
        for i in 1..10 {
            if i * i > 50 {
                break i; // 跳出内层循环,返回 i
            }
        }
        break 0; // 跳出外层循环,返回 0
    };
    println!("结果: {}", result);
}

break 返回值的作用域

rust 复制代码
fn main() {
    let result = 'outer: loop {
        let inner_result = loop {
            break 'outer 42; // 直接跳出外层循环并返回值
        };
        // 这里的代码不会执行
        break inner_result * 2;
    };
    
    println!("结果是: {}", result); // 42
}

5. 迭代器方法

Rust 的迭代器提供了丰富的链式方法。

基本迭代器方法

rust 复制代码
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // map: 转换每个元素
    let doubled: Vec<i32> = numbers.iter()
        .map(|x| x * 2)
        .collect();
    println!("翻倍后: {:?}", doubled); // [2, 4, 6, 8, 10]
    
    // filter: 过滤元素
    let evens: Vec<&i32> = numbers.iter()
        .filter(|&x| x % 2 == 0)
        .collect();
    println!("偶数: {:?}", evens); // [2, 4]
    
    // fold: 累积计算
    let sum = numbers.iter()
        .fold(0, |acc, x| acc + x);
    println!("总和: {}", sum); // 15
    
    // enumerate: 获取索引和值
    for (index, value) in numbers.iter().enumerate() {
        println!("索引 {}: 值 {}", index, value);
    }
}

链式迭代器操作

rust 复制代码
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    let result: Vec<i32> = numbers.iter()
        .filter(|&x| x % 2 == 0)     // 只保留偶数
        .map(|x| x * 3)             // 乘以3
        .take(3)                    // 只取前3个
        .collect();
    
    println!("结果: {:?}", result); // [6, 12, 18]
    
    // 复杂的链式操作
    let complex_result: i32 = numbers.iter()
        .skip(2)                    // 跳过前2个
        .take(5)                    // 取5个
        .filter(|&x| x > &3)        // 大于3
        .map(|x| x * 2)             // 乘以2
        .sum();                     // 求和
    
    println!("复杂操作结果: {}", complex_result);
}

6. 循环表达式返回值

Rust 中所有循环结构都可以返回值。

各种循环的返回值

rust 复制代码
fn main() {
    // loop 返回值
    let loop_result = {
        let mut i = 0;
        loop {
            i += 1;
            if i >= 5 {
                break i * 10;
            }
        }
    };
    println!("loop 结果: {}", loop_result); // 50
    
    // while 返回值(通过块表达式)
    let while_result = {
        let mut i = 0;
        let mut sum = 0;
        while i < 5 {
            sum += i;
            i += 1;
        }
        sum  // 块表达式的返回值
    };
    println!("while 结果: {}", while_result); // 10
    
    // for 循环返回值
    let for_result = {
        let mut sum = 0;
        for i in 1..=5 {
            sum += i;
        }
        sum
    };
    println!("for 结果: {}", for_result); // 15
}

7. 性能考虑

迭代器 vs 索引循环

rust 复制代码
fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    
    // 推荐:使用迭代器(更安全,通常性能更好)
    let sum1: i32 = vec.iter().sum();
    
    // 不推荐:使用索引(容易越界)
    let mut sum2 = 0;
    for i in 0..vec.len() {
        sum2 += vec[i];
    }
    
    println!("sum1 = {}, sum2 = {}", sum1, sum2);
    
    // 需要索引时的推荐写法
    for (i, value) in vec.iter().enumerate() {
        println!("索引 {}: 值 {}", i, value);
    }
}

避免不必要的 collect()

rust 复制代码
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 不好:创建了中间集合
    let doubled: Vec<i32> = numbers.iter()
        .map(|x| x * 2)
        .collect();
    
    for num in &doubled {
        println!("{}", num);
    }
    
    // 更好:直接使用迭代器
    for num in numbers.iter().map(|x| x * 2) {
        println!("{}", num);
    }
    
    // 计算而不收集
    let sum_of_squares: i32 = numbers.iter()
        .map(|x| x * x)
        .sum();
    println!("平方和: {}", sum_of_squares);
}

8. 实际应用示例

示例1:查找元素

rust 复制代码
fn find_first_even(numbers: &[i32]) -> Option<i32> {
    for &num in numbers {
        if num % 2 == 0 {
            return Some(num);
        }
    }
    None
}

fn main() {
    let nums = vec![1, 3, 5, 4, 7];
    
    match find_first_even(&nums) {
        Some(even) => println!("找到第一个偶数: {}", even),
        None => println!("没有找到偶数"),
    }
}

示例2:矩阵处理

rust 复制代码
fn process_matrix(matrix: &[Vec<i32>]) -> Vec<i32> {
    let mut result = Vec::new();
    
    for row in matrix {
        let row_sum: i32 = row.iter().sum();
        result.push(row_sum);
        
        // 处理每行元素
        for &value in row {
            if value > 10 {
                println!("发现大值: {}", value);
            }
        }
    }
    
    result
}

fn main() {
    let matrix = vec![
        vec![1, 2, 3],
        vec![4, 5, 6],
        vec![7, 8, 9],
    ];
    
    let sums = process_matrix(&matrix);
    println!("每行和: {:?}", sums); // [6, 15, 24]
}

示例3:游戏循环

rust 复制代码
struct Game {
    score: u32,
    lives: u8,
    level: u8,
}

impl Game {
    fn new() -> Self {
        Game {
            score: 0,
            lives: 3,
            level: 1,
        }
    }
    
    fn play(&mut self) -> u32 {
        println!("游戏开始!");
        
        'game_loop: loop {
            println!("=== 第 {} 关,生命: {},分数: {} ===", 
                    self.level, self.lives, self.score);
            
            // 关卡逻辑
            for enemy in 1..=5 {
                println!("遇到敌人 {}", enemy);
                
                // 模拟战斗
                if self.lives == 0 {
                    println!("游戏结束!");
                    break 'game_loop;
                }
                
                if rand::random() { // 50% 几率获胜
                    self.score += 100;
                    println!("击败敌人! +100 分");
                } else {
                    self.lives -= 1;
                    println!("被攻击! 剩余生命: {}", self.lives);
                }
            }
            
            // 过关
            self.level += 1;
            self.score += 500; // 过关奖励
            
            if self.level > 3 {
                println!("通关!");
                break 'game_loop;
            }
        }
        
        self.score
    }
}

fn main() {
    let mut game = Game::new();
    let final_score = game.play();
    println!("最终分数: {}", final_score);
}

示例4:数据处理流水线

rust 复制代码
fn process_data_stream(data: Vec<Option<i32>>) -> Vec<i32> {
    let mut results = Vec::new();
    
    // 使用 while let 处理流式数据
    let mut stream = data.into_iter();
    
    while let Some(maybe_value) = stream.next() {
        if let Some(value) = maybe_value {
            // 处理有效数据
            if value > 0 {
                let processed = value * 2;
                results.push(processed);
                
                // 处理一定数量后提前退出
                if results.len() >= 10 {
                    break;
                }
            }
        }
    }
    
    results
}

fn main() {
    let data = vec![
        Some(1), Some(-2), None, Some(3), Some(4),
        Some(5), None, Some(6), Some(7), Some(8),
        Some(9), Some(10), Some(11), Some(12),
    ];
    
    let processed = process_data_stream(data);
    println!("处理结果: {:?}", processed);
}

9. 最佳实践总结

  1. 优先使用迭代器:更安全,表达力更强
  2. 避免索引循环:除非确实需要索引且性能要求高
  3. 合理使用循环标签:处理复杂嵌套循环
  4. 利用循环返回值:简化代码逻辑
  5. 注意所有权:在循环中使用引用避免移动
  6. 使用合适的循环结构
    • 已知迭代次数:使用 for
    • 条件循环:使用 while
    • 无限循环:使用 loop
    • 模式匹配循环:使用 while let

Rust 的循环系统结合了安全性、表达力和性能,是 Rust 编程中的重要组成部分。

相关推荐
liuxuzxx19 小时前
使用Rust构建MCP Server Stdio类型
rust·mcp
FAFU_kyp19 小时前
Rust 结构体(struct)
开发语言·后端·rust
分布式存储与RustFS20 小时前
MinIO社区版“躺平”,RustFS能接棒吗?
rust·开源项目·对象存储·企业存储·rustfs·minio国产化替代
rustfs20 小时前
使用 RustFS和 Arq,打造 PC 数据安全备份之道
分布式·docker·云原生·rust·开源
m0_7482523820 小时前
Foundation 表格的基本用法
开发语言·后端·rust
古城小栈20 小时前
Rust unsafe 一文全功能解析
开发语言·后端·rust
Amos_Web21 小时前
Rust实战(五):用户埋点数据分析(前)
后端·架构·rust
古城小栈1 天前
Rust 模式匹配 大合集
开发语言·后端·rust
古城小栈1 天前
Rust 宏 !
算法·rust
神话20091 天前
Rust 初体验与快速上手指南
android·rust