Skip to content

实战总结

> 综合运用条件、循环和模式匹配,通过实战练习建立程序控制流的设计能力。

完整示例

示例 1:FizzBuzz

rust
fn main() {
    println!("FizzBuzz (1-100):");
    println!("{:-^30}", "");

    for i in 1..=100 {
        match (i % 3, i % 5) {
            (0, 0) => println!("FizzBuzz"),
            (0, _) => println!("Fizz"),
            (_, 0) => println!("Buzz"),
            _ => println!("{}", i),
        }
    }
}
▶ Run

示例 2:猜数字游戏

rust
use std::io;

fn main() {
    println!("欢迎来到猜数字游戏!");
    println!("我已经想好了一个 1 到 100 之间的数字。");

    let secret_number = 42;  // 实际中可以用 random 生成
    let mut attempts = 0;

    loop {
        println!("\n请输入你的猜测:");

        let mut guess = String::new();
        io::stdin()
            .read_line(&mut guess)
            .expect("读取失败");

        let guess: i32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("请输入有效的数字!");
                continue;
            }
        };

        attempts += 1;

        match guess {
            n if n < secret_number => println!("太小了!"),
            n if n > secret_number => println!("太大了!"),
            _ => {
                println!("恭喜你猜对了!用了 {} 次尝试。", attempts);
                break;
            }
        }
    }
}
▶ Run

示例 3:打印乘法表

rust
fn main() {
    println!("╔═══════════════════════════════════════╗");
    println!("║           九九乘法表                  ║");
    println!("╠═══════════════════════════════════════╣");

    // 表头
    print!("║    ");
    for i in 1..=9 {
        print!("{:>4}", i);
    }
    println!("  ║");
    println!("╠═══════════════════════════════════════╣");

    // 表格内容
    for i in 1..=9 {
        print!("║ {:>2} ", i);
        for j in 1..=9 {
            print!("{:>4}", i * j);
        }
        println!("  ║");
    }

    println!("╚═══════════════════════════════════════╝");
}
▶ Run

示例 4:简单菜单系统

rust
use std::io;

fn main() {
    let mut running = true;

    while running {
        println!("\n╔════════════════╗");
        println!("║    主菜单      ║");
        println!("╠════════════════╣");
        println!("║ 1. 查看信息    ║");
        println!("║ 2. 修改设置    ║");
        println!("║ 3. 退出        ║");
        println!("╚════════════════╝");

        let mut input = String::new();
        io::stdin().read_line(&mut input).expect("读取失败");

        match input.trim() {
            "1" => show_info(),
            "2" => modify_settings(),
            "3" => {
                println!("再见!");
                running = false;
            }
            _ => println!("无效选项,请重新输入"),
        }
    }
}

fn show_info() {
    println!("\n=== 信息页面 ===");
    println!("这是一个示例菜单系统");
    println!("版本:1.0.0");
}

fn modify_settings() {
    println!("\n=== 设置页面 ===");
    println!("(设置功能待实现)");
}
▶ Run

调试技巧

打印执行流程

rust
fn main() {
    for i in 1..=5 {
        dbg!(i);  // 打印 i 的值和位置

        if i % 2 == 0 {
            println!("{} 是偶数", i);
        }
    }
}
▶ Run

条件断点

rust
fn main() {
    let numbers = [1, 2, 3, 4, 5];

    for (i, &num) in numbers.iter().enumerate() {
        // 只在特定条件下打印
        if num == 3 {
            println!("找到 3 了!索引:{}", i);
        }
    }
}
▶ Run

常见错误

错误 1:条件不是布尔值

rust
fn main() {
    let x = 5;

    // ❌ 错误:Rust 没有真值转换
    // if x {
    //     println!("真");
    // }

    // ✅ 正确
    if x != 0 {
        println!("非零");
    }
}
▶ Run

错误信息:

error[E0308]: mismatched types
 --> src/main.rs:4:8
  |
4 |     if x {
  |        ^ expected `bool`, found integer

错误 2:if 分支类型不一致

rust
fn main() {
    // ❌ 错误
    // let result = if true {
    //     5           // i32
    // } else {
    //     "five"      // &str
    // };

    // ✅ 正确:类型一致
    let result = if true {
        5
    } else {
        10
    };
    println!("result = {}", result);
}
▶ Run

错误信息:

error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:5:9
  |
3 |       let result = if true {
  |  __________________-
4 | |         5
  | |         - expected because of this
5 | |     } else {
6 | |         "five"
  | |         ^^^^^^ expected `i32`, found `&str`
7 | |     };
  | |_____- `if` and `else` have incompatible types

错误 3:范围不包含结束值

rust
fn main() {
    // 很多人误以为 1..5 包含 5
    for i in 1..5 {
        print!("{} ", i);  // 1 2 3 4
    }
    println!();

    // 包含 5 要用..=
    for i in 1..=5 {
        print!("{} ", i);  // 1 2 3 4 5
    }
}
▶ Run

错误 4:忘记 rev() 导致倒序错误

rust
fn main() {
    // ❌ 错误:(5..0) 是空范围
    for i in 5..0 {
        println!("{}", i);  // 不会输出任何东西
    }

    // ✅ 正确:使用 rev()
    for i in (0..=5).rev() {
        println!("{}", i);  // 5 4 3 2 1 0
    }
}
▶ Run

错误 5:在循环中修改集合

rust
fn main() {
    let mut numbers = vec![1, 2, 3];

    // ❌ 错误:不能在遍历时可变借用
    // for num in &numbers {
    //     numbers.push(*num);  // 错误!
    // }

    // ✅ 正确:先收集,再添加
    let to_add: Vec<_> = numbers.iter().copied().collect();
    for num in to_add {
        numbers.push(num);
    }
    println!("{:?}", numbers);
}
▶ Run

练习

练习 1:质数判断

编写程序,打印 1 到 100 之间的所有质数。

提示:质数是只能被 1 和自身整除的数。

练习 2:斐波那契数列

打印斐波那契数列的前 20 项: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34...

规则:每一项等于前两项之和。

练习 3:数字金字塔

打印以下图案:

    1
   121
  12321
 1234321
123454321

练习 4:简单计算器

实现一个带菜单的计算器,支持:

  • 加法
  • 减法
  • 乘法
  • 除法
  • 退出

小结

控制流结构对比

结构语法特点适用场景
ifif cond { }条件分支,可返回值条件判断
if letif let Some(x) = opt单一模式匹配Option/Result 处理
whilewhile cond { }条件循环未知次数的循环
while letwhile let Some(x) = iter.next()模式匹配循环迭代器
forfor x in iter迭代循环遍历集合
looploop { }无限循环,可返回值需要 break 的循环
matchmatch x { }穷尽模式匹配多分支选择

选择指南

需要条件分支?
├── 单一条件 → if
├── 多个条件 → if-else if-else
└── 模式匹配 → match

需要循环?
├── 已知次数/遍历集合 → for
├── 条件循环 → while
├── 无限循环 → loop
└── 模式匹配循环 → while let

关键要点

  1. Rust 的 if 是表达式,可以返回值
  2. 条件必须是布尔类型,没有真值转换
  3. for 循环最常用,推荐用于遍历集合
  4. range 不包含结束值1..5 是 1,2,3,4
  5. loop 可以返回值,使用 break value
  6. 循环标签用于控制嵌套循环

第 07 章:所有权与借用

练习题

详见:练习题