【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 编程中的重要组成部分。

相关推荐
Source.Liu2 小时前
【Rust】元组:轻量级数据组合利器
rust
RustFS8 小时前
RustFS 如何实现对象存储的前端直传?
vue.js·docker·rust
沐森11 小时前
使用rust打开node的libuv实现多线程调用三种模式
javascript·rust
苏近之12 小时前
Rust 基于 Tokio 实现任务管理器
后端·架构·rust
Source.Liu14 小时前
【Rust】方法重载
rust
QC七哥14 小时前
基于tauri构建全平台应用
rust·electron·nodejs·tauri
wadesir1 天前
Rust中的条件变量详解(使用Condvar的wait方法实现线程同步)
开发语言·算法·rust
hans汉斯1 天前
嵌入式操作系统技术发展趋势
大数据·数据库·物联网·rust·云计算·嵌入式实时数据库·汉斯出版社
Source.Liu1 天前
【Rust】布尔类型详解
rust