Rust基础

第3课:控制流

🎯 本课目标

掌握Rust的条件判断、循环、迭代,以及表达式驱动的控制流特色。

1. if表达式

Rust的if是表达式,可以返回值:

fn main() {
    let number = 7;
    if number % 4 == 0 {
        println!("能被4整除");
    } else if number % 3 == 0 {
        println!("能被3整除");
    } else {
        println!("其他");
    }

    // if作为表达式——替代三目运算符
    let x = if true { 5 } else { 6 };
    println!("x = {}", x);
}

✅ 编译验证通过

💡 表达式vs语句:块表达式的值是最后一个表达式的值(无分号):
let y = {
    let x = 3;
    x + 1   // 无分号!这是返回值
};  // y = 4

2. 循环

2.1 loop — 无限循环

fn main() {
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2;  // 返回20
        }
    };

    // 循环标签——跳出外层
    'outer: loop {
        loop {
            break 'outer;
        }
    }
}

✅ 编译验证通过

2.2 while循环

fn main() {
    let mut n = 1;
    while n < 100 { n *= 2; }
    println!("n = {}", n);  // 128
}

✅ 编译验证通过

2.3 for循环 — 最常用

fn main() {
    let arr = [10, 20, 30, 40, 50];
    for elem in arr {
        println!("值: {}", elem);
    }

    // Range
    for i in 0..5 { println!("i={}", i); }  // 0-4
    for i in 1..=5 { println!("i={}", i); } // 1-5

    // 反向、带索引、步长
    for i in (1..=5).rev() { /* 5,4,3,2,1 */ }
    for (i, &e) in arr.iter().enumerate() { /* 索引+值 */ }
    for i in (0..10).step_by(2) { /* 0,2,4,6,8 */ }
}

✅ 编译验证通过

3. match表达式

fn main() {
    let number = 13;
    match number {
        1 => println!("一"),
        2 | 3 | 5 | 7 | 11 => println!("质数"),
        13..=19 => println!("青少年数字"),
        n if n % 2 == 0 => println!("偶数: {}", n),
        _ => println!("其他"),
    }

    // match是表达式
    let grade = 85;
    let letter = match grade {
        90..=100 => "A",
        80..=89 => "B",
        70..=79 => "C",
        60..=69 => "D",
        _ => "F",
    };
}

✅ 编译验证通过

4. if let与while let

fn main() {
    let value: Option<i32> = Some(42);

    // match写法
    match value {
        Some(n) => println!("值: {}", n),
        _ => (),
    }

    // if let更简洁
    if let Some(n) = value {
        println!("if let: {}", n);
    }

    // while let
    let mut stack = vec![1, 2, 3];
    while let Some(top) = stack.pop() {
        println!("弹出: {}", top);
    }
}

✅ 编译验证通过

5. break与continue

fn main() {
    for i in 0..10 {
        if i % 2 == 0 { continue; }
        println!("奇数: {}", i);
    }

    let found = 'search: {
        for i in 0..100 {
            for j in 0..100 {
                if i * j == 567 {
                    break 'search (i, j);
                }
            }
        }
        (0, 0)
    };
}

✅ 编译验证通过

6. 控制流的内存模型

循环执行时栈帧变化: for i in 0..3 { ┌─────────┐ │ i = 0 │ ← 第1次迭代 └─────────┘ ┌─────────┐ │ i = 1 │ ← 第2次迭代 └─────────┘ ┌─────────┐ │ i = 2 │ ← 第3次迭代 └─────────┘ 每次迭代i是新的不可变绑定 循环体内创建的变量在每次迭代结束时drop

📝 练习题

练习1:FizzBuzz

for n in 1..=30 {
    let out = match (n%3, n%5) {
        (0,0) => "FizzBuzz",
        (0,_) => "Fizz",
        (_,0) => "Buzz",
        _ => format!("{}",n).leak(),
    };
    print!("{} ", out);
}

练习2:二分查找

用while循环实现二分查找。

练习3:嵌套循环优化

使用标签和break提前退出,查找第一个满足i²+j²=n的解。

🏆

成就解锁:流程掌控者

掌握Rust所有控制流结构,理解表达式驱动范式


📚 扩展阅读

以下资源帮助你深入学习本课主题:

🔑 关键术语回顾

本课涉及的核心概念,确保你理解每一个:

术语说明
所有权Rust内存管理的核心机制,每个值有唯一所有者
借用通过引用访问数据,不获取所有权
生命周期引用有效的范围,编译期分析工具
traitRust的接口/抽象机制,类似其他语言的接口
泛型参数化类型,零成本抽象
模式匹配强大的数据解构和分支机制
零成本抽象高层抽象不引入运行时开销
fearless concurrency编译器保证线程安全

💬 学习建议

  1. 动手编码 — 每个代码示例都在本地运行一遍
  2. 修改实验 — 故意改错代码,看编译器报什么错
  3. 完成练习 — 每课的练习题是巩固知识的关键
  4. 阅读源码 — 看标准库和优秀开源项目的实现
  5. 写项目 — 真正掌握需要构建真实项目

🤔 常见问题

Q: Rust学习曲线真的很陡吗?

A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。

Q: Rust适合什么项目?

A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。

Q: 遇到编译错误怎么办?

A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。