
第 4 章 控制流
4.1 条件表达式 if/else
4.1.1 基础条件表达式
在 Rust 中,条件表达式是程序决策的基础。与其他语言不同,Rust 的 if 表达式总是返回一个值,这使得它们更加灵活和强大。
fn basic_conditionals() {
println!("=== 基础条件表达式 ===");
// 1. 基本的 if 表达式
let number = 7;
if number < 5 {
println!("条件为真");
} else {
println!("条件为假");
}
// 2. 多条件判断
let score = 85;
if score >= 90 {
println!("优秀");
} else if score >= 80 {
println!("良好");
} else if score >= 70 {
println!("中等");
} else if score >= 60 {
println!("及格");
} else {
println!("不及格");
}
// 3. if 作为表达式(返回值的 if)
let condition = true;
let result = if condition { "真分支的值" } else { "假分支的值" };
println!("if 表达式结果:{}", result);
// 4. 在 let 语句中使用 if 表达式
let number = 6;
let is_even = if number % 2 == 0 { "偶数" } else { "奇数" };
println!("{} 是 {}", number, is_even);
// 5. 嵌套 if 表达式
let x = 10;
let y = 20;
let comparison = if x > y { "x 大于 y" } else if x < y { "x 小于 y" } else { "x 等于 y" };
println!("比较结果:{}", comparison);
// 6. 布尔值的隐式转换
let flag = true;
if flag { // 不需要写 if flag == true
println!("标志为真");
}
if !flag { // 不需要写 if flag == false
println!("标志为假");
}
}
4.1.2 高级条件表达式模式
让我们探索一些更高级的条件表达式用法和模式。
fn advanced_conditional_patterns() {
println!("=== 高级条件表达式模式 ===");
// 1. 守卫条件 (guard clauses)
fn process_user(age: Option<u32>, has_consent: bool) -> String {
// 早期返回模式
if age.is_none() {
return "年龄信息缺失".to_string();
}
let age = age.unwrap();
if !has_consent {
return "需要用户同意".to_string();
}
if age < 18 {
return "用户未成年".to_string();
}
"处理成功".to_string()
}
println!("守卫条件示例:{}", process_user(Some(20), true));
// 2. 条件赋值模式
let mut counter = 0;
let max_attempts = 3;
while let true = { counter += 1; counter <= max_attempts } {
println!("尝试 {} of {}", counter, max_attempts);
}
// 3. 复杂布尔表达式
let is_weekday = true;
let is_holiday = false;
let has_meeting = true;
let workload = 75; // 百分比
let should_work_from_home = (is_weekday && !is_holiday) && (has_meeting || workload > 80);
println!("应该在家办公:{}", should_work_from_home);
// 4. 模式匹配风格的 if let
let config = Some("production");
if let Some(env) = config {
println!("运行在 {} 环境", env);
}
// 5. 多变量条件绑定
let point = (5, 10);
if let (x, y) = point {
if x > 0 && y > 0 {
println!("点 ({}, {}) 在第一象限", x, y);
}
}
// 6. 条件表达式与错误处理
fn parse_number(s: &str) -> Result<i32, String> {
if s.is_empty() {
return Err("字符串为空".to_string());
}
if !s.chars().all(|c| c.is_ascii_digit()) {
return Err("包含非数字字符".to_string());
}
Ok(s.parse().unwrap())
}
match parse_number("123") {
Ok(num) => println!("解析成功:{}", num),
Err(e) => println!("解析失败:{}", e),
}
// 7. 条件编译
#[cfg(debug_assertions)]
{
println!("这是调试构建");
}
#[cfg(not(debug_assertions))]
{
println!("这是发布构建");
}
// 8. 基于特性的条件编译
#[cfg(feature = "logging")]
{
println!("日志特性已启用");
}
}
4.2 循环:loop、while、for
4.2.1 loop 循环深度解析
loop 循环是 Rust 中最基本的循环结构,它会无限循环直到显式中断。
fn loop_deep_dive() {
println!("=== loop 循环深度解析 ===");
// 1. 基本 loop 循环
let mut counter = 0;
loop {
counter += 1;
println!("循环次数:{}", counter);
if counter >= 5 {
break;
}
}
// 2. loop 返回值
let result = loop {
counter += 1;
if counter >= 10 {
break counter * 2; // loop 可以返回值
}
};
println!("loop 返回值:{}", result);
// 3. 嵌套 loop 和标签
'outer: loop {
println!("进入外部循环");
let mut inner_counter = 0;
'inner: loop {
inner_counter += 1;
println!(" 内部循环:{}", inner_counter);
if inner_counter >= 3 {
break 'inner; // 跳出内部循环
}
}
counter += 1;
if counter >= 2 {
break 'outer; // 跳出外部循环
}
}
// 4. loop 与模式匹配
let mut values = vec![1, 2, 3, 4, 5].into_iter();
loop {
match values.next() {
Some(value) => {
println!("处理值:{}", value);
if value == 3 {
println!("找到目标值,继续处理...");
continue; // 跳过当前迭代的剩余部分
}
}
None => {
println!("没有更多值");
break;
}
}
}
// 5. 条件循环模拟
let mut number = 0;
loop {
number += 1; // 使用条件控制循环
if number % 2 == 0 {
continue; // 跳过偶数
}
println!("奇数:{}", number);
if number >= 9 {
break;
}
}
// 6. 复杂循环控制
complex_loop_control();
}
4.2.2 while 循环深度解析
while 循环在满足条件时重复执行代码块。
fn while_loop_deep_dive() {
println!("=== while 循环深度解析 ===");
// 1. 基本 while 循环
let mut counter = 0;
while counter < 5 {
println!("计数器:{}", counter);
counter += 1;
}
// 2. while let 模式
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
println!("栈内容:");
while let Some(top) = stack.pop() {
println!("弹出:{}", top);
}
// 3. 复杂的 while 条件
let mut x = 100;
while x > 0 {
x /= 2;
if x == 0 {
break;
}
println!("x = {}", x);
}
// 4. 使用 while 进行输入处理
process_user_input_simulation();
// 5. while 循环与迭代器
let numbers = [1, 2, 3, 4, 5];
let mut iter = numbers.iter();
while let Some(&number) = iter.next() {
if number == 3 {
println!("找到 3,跳过剩余");
break;
}
println!("处理数字:{}", number);
}
// 6. 条件递减循环
let mut remaining_time = 10;
while remaining_time > 0 {
println!("倒计时:{}秒", remaining_time);
remaining_time -= 1;
std::thread::sleep(std::time::Duration::from_millis(100));
}
println!("时间到!");
}
4.2.3 for 循环深度解析
for 循环是 Rust 中最常用的循环结构,主要用于迭代集合。
fn for_loop_deep_dive() {
println!("=== for 循环深度解析 ===");
// 1. 基本 for 循环 - 范围迭代
println!("范围迭代:");
for i in 0..5 { // 0 到 4(不包含 5)
println!("i = {}", i);
}
println!("包含范围:");
for i in 0..=5 { // 0 到 5(包含 5)
println!("i = {}", i);
}
// 2. 数组迭代
let numbers = [10, 20, 30, 40, 50];
println!("数组迭代:");
for number in numbers {
println!("数字:{}", number);
}
// 3. 向量迭代
let names = vec!["Alice", "Bob", "Charlie"];
println!("向量迭代:");
for name in &names { // 使用引用避免所有权转移
println!("名字:{}", name);
}
// 4. 带索引的迭代
println!("带索引迭代:");
for (index, name) in names.iter().enumerate() {
println!("索引 {}: {}", index, name);
}
// 5. 字符串字符迭代
let text = "Hello, 世界!";
println!("字符迭代:");
for (i, ch) in text.chars().enumerate() {
println!("位置 {}: '{}' (U+{:04X})", i, ch, ch as u32);
}
// 6. 字节迭代
println!("字节迭代:");
for byte in text.bytes() {
println!("字节:0x{:02X}", byte);
}
// 7. 哈希映射迭代
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Alice", 100);
scores.insert("Bob", 85);
scores.insert("Charlie", 92);
println!("哈希映射迭代:");
for (name, score) in &scores {
println!("{}: {}", name, score);
}
// 8. 反向迭代
println!("反向迭代:");
for i in (0..5).rev() {
println!("i = {}", i);
}
// 9. 步长迭代
println!("步长迭代:");
for i in (0..20).step_by(3) {
println!("i = {}", i);
}
// 10. 嵌套 for 循环
println!("嵌套循环:");
for i in 0..3 {
for j in 0..3 {
println!("({}, {})", i, j);
}
}
// 11. 复杂的 for 循环模式
advanced_for_patterns();
}
4.3 模式匹配与 match 表达式
4.3.1 match 表达式基础
match 是 Rust 中最强大的控制流工具之一,提供全面的模式匹配能力。
fn match_expression_basics() {
println!("=== match 表达式基础 ===");
// 1. 基本 match 表达式
let number = 13;
match number {
1 => println!("一"),
2 | 3 | 5 | 7 | 11 => println!("质数"),
13..=19 => println!("青少年数字"),
_ => println!("其他数字"),
}
// 2. match 返回值的用法
let number = 5;
let description = match number {
1 => "一",
2 => "二",
3 => "三",
_ => "很多",
};
println!("数字 {} 是 {}", number, description);
// 3. 匹配布尔值
let flag = true;
match flag {
true => println!("真"),
false => println!("假"),
}
// 4. 匹配字符
let grade = 'A';
match grade {
'A' | 'B' | 'C' => println!("及格"),
'D' => println!("勉强及格"),
'F' => println!("不及格"),
_ => println!("无效成绩"),
}
// 5. 匹配字符串切片
let language = "Rust";
match language {
"Rust" => println!("系统编程语言"),
"Python" => println!("脚本语言"),
"Java" => println!("企业级语言"),
_ => println!("其他语言"),
}
// 6. 穷尽性检查
let boolean = true; // 必须处理所有可能的情况
match boolean {
true => println!("真"),
false => println!("假"),
}
// 7. 使用 _ 通配符
let value = 42;
match value {
1 => println!("一"),
2 => println!("二"),
_ => (), // 忽略其他所有情况
}
// 8. 匹配范围
let age = 25;
match age {
0..=12 => println!("儿童"),
13..=19 => println!("青少年"),
20..=64 => println!("成人"),
_ => println!("长者"),
}
}
4.3.2 if let 和 while let
if let 和 while let 提供了模式匹配的简洁语法。
fn if_let_while_let_patterns() {
println!("=== if let 和 while let 模式 ===");
// 1. 基本 if let 用法
let some_value = Some(5);
// 使用 match
match some_value {
Some(x) => println!("值为:{}", x),
None => (),
}
// 使用 if let(更简洁)
if let Some(x) = some_value {
println!("值为:{}", x);
}
// 2. if let 与 else
let none_value: Option<i32> = None;
if let Some(x) = none_value {
println!("有值:{}", x);
} else {
println!("没有值");
}
// 3. if let 与守卫条件
let some_number = Some(10);
if let Some(x) = some_number {
if x > 5 {
println!("值 {} 大于 5", x);
}
}
// 使用守卫的更简洁写法
if let Some(x) = some_number && x > 5 {
println!("值 {} 大于 5", x);
}
// 4. 解构复杂类型
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
}
let event = Event::Click { x: 100, y: 200 };
if let Event::Click { x, y } = event {
println!("点击位置:({}, {})", x, y);
}
// 5. while let 循环
let mut stack = Vec::new();
stack.push(1);
stack.push(2);
stack.push(3);
println!("使用 while let 弹出栈:");
while let Some(top) = stack.pop() {
println!("弹出:{}", top);
}
// 6. while let 与迭代器
let numbers = vec![1, 2, 3, 4, 5];
let mut iter = numbers.iter();
println!("使用 while let 迭代:");
while let Some(&number) = iter.next() {
println!("数字:{}", number);
}
// 7. 复杂条件的 while let
let mut optional = Some(0);
while let Some(i) = optional {
if i > 9 {
println!("大于 9,退出");
optional = None;
} else {
println!("`i` 是 `{:?}`,继续", i);
optional = Some(i + 1);
}
}
// 8. if let 在赋值中
let config_max = Some(3u8);
// 使用 if let 进行条件赋值
let max_value = if let Some(max) = config_max { max } else { 0u8 };
println!("最大值:{}", max_value);
// 9. 模式匹配与错误处理
let result: Result<i32, &str> = Ok(42);
if let Ok(value) = result {
println!("成功:{}", value);
}
if let Err(error) = result {
println!("错误:{}", error);
}
// 10. 实际应用示例
practical_if_let_examples();
}
4.4 控制流最佳实践
4.4.1 代码可读性与维护性
编写清晰、易于理解的控制流代码。
fn readability_best_practices() {
println!("=== 代码可读性最佳实践 ===");
// 1. 使用有意义的变量名
let user_age = 25;
let has_driving_license = true;
// 好:条件清晰易读
if user_age >= 18 && has_driving_license {
println!("可以驾驶");
}
// 不好:使用魔法数字和无意义的名字
let a = 25;
let b = true;
if a >= 18 && b {
println!("可以驾驶");
}
// 2. 避免过深的嵌套
complex_nested_logic();
refactored_complex_logic();
// 3. 使用守卫子句提前返回
fn process_user_data(name: Option<&str>, age: Option<u32>) -> Result<String, String> {
// 守卫子句:提前处理错误情况
let name = name.ok_or("姓名缺失")?;
let age = age.ok_or("年龄缺失")?;
if name.is_empty() {
return Err("姓名为空".to_string());
}
if age < 18 {
return Err("用户未成年".to_string());
}
Ok(format!("用户 {} 年龄 {}", name, age))
}
// 4. 使用布尔变量简化复杂条件
let temperature = 25;
let is_weekend = true;
let has_plans = false;
// 复杂条件
if temperature > 20 && temperature < 30 && is_weekend && !has_plans {
println!("好天气,没安排,出门吧!");
}
// 使用布尔变量简化
let good_weather = temperature > 20 && temperature < 30;
let free_time = is_weekend && !has_plans;
if good_weather && free_time {
println!("好天气,没安排,出门吧!");
}
// 5. 匹配枚举时使用穷尽模式
enum TrafficLight {
Red,
Yellow,
Green,
}
let light = TrafficLight::Red;
// 好:处理所有情况
match light {
TrafficLight::Red => println!("停止"),
TrafficLight::Yellow => println!("准备"),
TrafficLight::Green => println!("通行"),
}
// 6. 使用注释解释复杂逻辑
let score = 85; // 成绩等级划分逻辑
let grade = match score {
// 90 分以上为优秀
90..=100 => "优秀",
// 80-89 分为良好
80..=89 => "良好",
// 70-79 分为中等
70..=79 => "中等",
// 60-69 分为及格
60..=69 => "及格",
// 其他为不及格
_ => "不及格",
};
println!("成绩等级:{}", grade);
}
4.4.2 错误处理模式
在控制流中优雅地处理错误。
fn error_handling_patterns() {
println!("=== 错误处理模式 ===");
// 1. 使用 Result 和 match
fn parse_number(s: &str) -> Result<i32, String> {
s.parse().map_err(|_| "解析失败".to_string())
}
let input = "42";
match parse_number(input) {
Ok(number) => println!("解析成功:{}", number),
Err(error) => println!("解析失败:{}", error),
}
// 2. 使用 ? 操作符简化错误传播
fn process_data(data: &str) -> Result<i32, String> {
let num1 = parse_number(data)?;
let num2 = parse_number("100")?;
Ok(num1 + num2)
}
// 3. 组合错误处理
fn comprehensive_data_processing(input: &str) -> Result<String, String> {
// 多个可能失败的操作
let number = input.parse::<i32>().map_err(|_| "数字解析失败".to_string())?;
if number < 0 {
return Err("数字不能为负".to_string());
}
if number > 1000 {
return Err("数字太大".to_string());
}
Ok(format!("处理后的数字:{}", number * 2))
}
// 4. 使用 if let 处理特定错误
let result = comprehensive_data_processing("5000");
if let Err(error) = &result {
if error == "数字太大" {
println!("数字超出范围,但可以继续处理");
}
}
// 5. 错误转换
fn convert_errors() -> Result<(), String> {
let input = "not_a_number";
// 将不同的错误类型转换为统一的错误类型
let _number: i32 = input.parse().map_err(|e| format!("解析错误:{}", e))?;
Ok(())
}
// 6. 可选值处理模式
fn find_user(name: &str) -> Option<&str> {
if name == "admin" {
Some("管理员用户")
} else {
None
}
}
let user = find_user("admin");
match user {
Some(user_info) => println!("找到用户:{}", user_info),
None => println!("用户不存在"),
}
// 7. 使用 unwrap_or 提供默认值
let user = find_user("guest").unwrap_or("默认用户");
println!("用户:{}", user);
// 8. 链式错误处理
fn complex_operation() -> Result<i32, String> {
Ok(42)
}
let final_result = complex_operation().and_then(|x| Ok(x * 2)).and_then(|x| if x > 50 { Ok(x) } else { Err("值太小".to_string()) });
match final_result {
Ok(value) => println!("最终结果:{}", value),
Err(error) => println!("处理失败:{}", error),
}
}
通过本章的全面学习,你已经深入掌握了 Rust 的控制流系统。从基础的条件表达式到复杂的模式匹配,从简单的循环到高级的迭代器模式,你现在应该能够编写出既安全又高效的 Rust 控制流代码。在下一章中,我们将深入探讨 Rust 最独特的特性:所有权系统。


