1. if/else 表达式

在 Rust 中,if 是一个表达式,可以返回值。条件必须是 bool 类型,不会自动转换。

1.1 基本 if/else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn main() {
let number = 7;

// 基本 if
if number > 5 {
println!("{} 大于 5", number);
}

// if/else
if number % 2 == 0 {
println!("{} 是偶数", number);
} else {
println!("{} 是奇数", number);
}

// if/else if/else
if number < 0 {
println!("负数");
} else if number == 0 {
println!("零");
} else if number < 10 {
println!("一位正数");
} else {
println!("多位正数");
}
}

1.2 if 作为表达式(返回值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
fn main() {
let condition = true;

// if 是表达式,可以将结果赋给变量
let number = if condition { 5 } else { 10 };
println!("number = {}", number); // 5

// 类似三元运算符(Rust 没有 ?: 运算符)
let x = 42;
let description = if x > 0 { "正数" } else if x == 0 { "零" } else { "负数" };
println!("{} 是{}", x, description);

// 注意:if/else 分支必须返回相同类型
// let bad = if condition { 5 } else { "hello" };
// 编译错误:`if` and `else` have incompatible types

// 如果 if 没有 else,则返回 ()
let result = if condition { println!("true 分支"); };
println!("无 else 时返回: {:?}", result); // ()

// if 表达式嵌入到其他表达式中
let score = 85;
let grade = String::from("成绩等级: ") +
if score >= 90 { "A" }
else if score >= 80 { "B" }
else if score >= 70 { "C" }
else if score >= 60 { "D" }
else { "F" };
println!("{}", grade);
}

1.3 条件必须是 bool 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn main() {
let number = 3;

// Rust 不会自动将非布尔值转换为布尔值
// if number { // 编译错误!expected `bool`, found integer
// println!("数字非零");
// }

// 必须显式写条件表达式
if number != 0 {
println!("数字 {} 非零", number);
}

// 字符串也一样
let name = "Rust";
// if name { // 编译错误!
// println!("name 非空");
// }

if !name.is_empty() {
println!("name 不为空: {}", name);
}
}

2. if let 表达式

if let 是一种简洁的模式匹配语法,适用于只关心一种匹配情况的场景。

2.1 基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
let some_value: Option<i32> = Some(42);

// 使用 match(完整但冗长)
match some_value {
Some(value) => println!("match: 值是 {}", value),
None => (), // 必须处理所有分支
}

// 使用 if let(简洁版)
if let Some(value) = some_value {
println!("if let: 值是 {}", value);
}

// if let 搭配 else
let none_value: Option<i32> = None;
if let Some(value) = none_value {
println!("有值: {}", value);
} else {
println!("没有值");
}
}

2.2 匹配枚举变体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#[derive(Debug)]
enum Coin {
Penny,
Nickel,
Dime,
Quarter(String), // 带数据的变体
}

fn main() {
let coin = Coin::Quarter(String::from("Alaska"));

// 只关心 Quarter 的情况
if let Coin::Quarter(state) = &coin {
println!("这是一个来自 {} 的 25 美分硬币!", state);
} else {
println!("不是 25 美分硬币");
}

// 多个条件组合
let number: Option<i32> = Some(7);
if let Some(n) = number {
if n > 5 {
println!("{} 大于 5", n);
}
}
}

2.3 if let 链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fn main() {
let config_max: Option<u8> = Some(3);
let config_min: Option<u8> = Some(1);

// if let 与 else if let 链
if let Some(max) = config_max {
println!("最大值设置为 {}", max);
} else if let Some(min) = config_min {
println!("只设置了最小值 {}", min);
} else {
println!("没有设置任何限制");
}

// 结合普通 if 条件
let age: Option<u32> = Some(25);
let is_student = true;

if let Some(a) = age {
if a < 18 {
println!("未成年");
} else if is_student {
println!("{} 岁的学生", a);
} else {
println!("{} 岁的成年人", a);
}
}
}

2.4 let-else(Rust 1.65+)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
// let-else: 匹配失败时必须发散(return、break、panic 等)
let config: Option<&str> = Some("enabled");

let Some(value) = config else {
println!("配置缺失,退出");
return;
};
println!("配置值: {}", value);

// 常用于函数中提前返回
process_input("42");
process_input("not a number");
}

fn process_input(input: &str) {
let Ok(number) = input.parse::<i32>() else {
println!("'{}' 不是有效数字,跳过", input);
return;
};
println!("解析得到数字: {}", number);
}

3. loop 循环

loop 创建无限循环。

3.1 基本 loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn main() {
let mut count = 0;

loop {
count += 1;
println!("第 {} 次循环", count);

if count >= 5 {
break; // 使用 break 退出循环
}
}

println!("循环结束,总共 {} 次", count);
}

3.2 loop 返回值

loop 可以通过 break 返回值,这是 Rust 独特的特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
fn main() {
let mut counter = 0;

// loop 表达式可以返回值
let result = loop {
counter += 1;

if counter == 10 {
break counter * 2; // break 后面的值就是 loop 的返回值
}
};

println!("counter = {}, result = {}", counter, result); // 10, 20

// 实际应用:重试直到成功
let mut attempts = 0;
let data = loop {
attempts += 1;
let simulated_result = if attempts >= 3 { Some("数据") } else { None };

if let Some(value) = simulated_result {
break value; // 成功,返回值
}

println!("第 {} 次尝试失败,重试...", attempts);
};
println!("经过 {} 次尝试获得: {}", attempts, data);
}

3.3 循环标签(Label)

嵌套循环中使用标签来指定 breakcontinue 的目标循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
fn main() {
let mut outer_count = 0;

// 'outer 是循环标签(以单引号开头)
'outer: loop {
outer_count += 1;
println!("外层循环 #{}", outer_count);

let mut inner_count = 0;

'inner: loop {
inner_count += 1;
println!(" 内层循环 #{}", inner_count);

if inner_count == 3 {
break 'inner; // 退出内层循环
}

if outer_count == 2 && inner_count == 2 {
println!(" 从内层退出外层循环!");
break 'outer; // 从内层退出外层循环
}
}

if outer_count >= 5 {
break; // 退出外层循环
}
}

println!("所有循环结束");

// 标签 + 返回值
let result = 'search: loop {
for i in 0..10 {
for j in 0..10 {
if i * j == 42 {
break 'search (i, j); // 返回找到的值
}
}
}
break 'search (0, 0); // 未找到
};
println!("找到 i*j=42: {:?}", result); // (6, 7)
}

4. while 循环

4.1 基本 while

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fn main() {
// 基本 while 循环
let mut number = 5;

while number > 0 {
println!("{}!", number);
number -= 1;
}
println!("发射!");

println!();

// 遍历数组(不推荐,用 for 更好)
let arr = [10, 20, 30, 40, 50];
let mut index = 0;

while index < arr.len() {
println!("arr[{}] = {}", index, arr[index]);
index += 1;
}
}

4.2 while 与条件表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fn main() {
// 模拟猜数字
let secret = 42;
let guesses = [10, 30, 42, 50];
let mut index = 0;

while index < guesses.len() {
let guess = guesses[index];
println!("猜测: {}", guess);

if guess == secret {
println!("猜对了!");
break;
} else if guess < secret {
println!("太小了");
} else {
println!("太大了");
}

index += 1;
}

// while true 等价于 loop(但推荐用 loop)
let mut count = 0;
while count < 3 {
count += 1;
}
println!("while 循环计数: {}", count);
}

5. while let 循环

while let 循环在模式匹配成功时持续执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
fn main() {
// ========== 基本 while let ==========
let mut stack = vec![1, 2, 3, 4, 5];

// pop() 返回 Option<T>,当栈非空时持续弹出
while let Some(top) = stack.pop() {
println!("弹出: {}", top);
}
println!("栈为空: {:?}", stack);

println!();

// ========== 处理迭代器 ==========
let mut iter = (0..5).into_iter();

while let Some(value) = iter.next() {
println!("迭代器值: {}", value);
}

println!();

// ========== 处理 Result ==========
let inputs = vec!["42", "hello", "7", "world", "13"];
let mut numbers = Vec::new();
let mut iter = inputs.iter();

// 收集所有能解析为数字的值
while let Some(input) = iter.next() {
if let Ok(num) = input.parse::<i32>() {
numbers.push(num);
}
}
println!("解析到的数字: {:?}", numbers);

println!();

// ========== 嵌套 Option ==========
let mut data: Option<Option<i32>> = Some(Some(42));

while let Some(inner) = data {
if let Some(value) = inner {
println!("嵌套值: {}", value);
}
data = None; // 修改条件,退出循环
}

// ========== 对比 while let 和 loop + match ==========
let mut optional = Some(0);

// while let 写法(简洁)
while let Some(i) = optional {
if i > 3 {
println!("大于 3,退出");
optional = None;
} else {
println!("while let: {}", i);
optional = Some(i + 1);
}
}
}

6. for 循环

for 循环是 Rust 中最常用的循环结构。

6.1 遍历集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
fn main() {
// ========== 遍历数组 ==========
let arr = [10, 20, 30, 40, 50];

// 遍历引用(最常用)
for element in &arr {
print!("{} ", element);
}
println!();

// 遍历值(如果元素实现了 Copy)
for element in arr {
print!("{} ", element);
}
println!();

// ========== 遍历 Vec ==========
let fruits = vec!["苹果", "香蕉", "橙子"];

// 借用遍历(不转移所有权)
for fruit in &fruits {
println!("水果: {}", fruit);
}
println!("fruits 仍然有效: {:?}", fruits);

// 可变引用遍历
let mut numbers = vec![1, 2, 3, 4, 5];
for num in &mut numbers {
*num *= 2; // 修改每个元素
}
println!("加倍后: {:?}", numbers);

// 消费遍历(转移所有权)
let names = vec![String::from("Alice"), String::from("Bob")];
for name in names {
println!("Hello, {}!", name);
}
// println!("{:?}", names); // 编译错误!names 已被消费
}

6.2 Range 表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
fn main() {
// 半开区间 (start..end):包含 start,不包含 end
println!("=== 0..5 ===");
for i in 0..5 {
print!("{} ", i); // 0 1 2 3 4
}
println!();

// 闭区间 (start..=end):包含 start 和 end
println!("=== 1..=5 ===");
for i in 1..=5 {
print!("{} ", i); // 1 2 3 4 5
}
println!();

// 反向迭代
println!("=== (1..=5).rev() ===");
for i in (1..=5).rev() {
print!("{} ", i); // 5 4 3 2 1
}
println!();

// 步进(使用 step_by)
println!("=== (0..20).step_by(3) ===");
for i in (0..20).step_by(3) {
print!("{} ", i); // 0 3 6 9 12 15 18
}
println!();

// 字符范围
println!("=== 'a'..='f' ===");
for c in 'a'..='f' {
print!("{} ", c); // a b c d e f
}
println!();

// Range 的方法
let range = 1..=100;
println!("\n1..=100 包含 50: {}", range.contains(&50));
}

6.3 enumerate(带索引遍历)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fn main() {
let fruits = vec!["苹果", "香蕉", "橙子", "葡萄", "西瓜"];

// enumerate 返回 (索引, 值) 元组
for (index, fruit) in fruits.iter().enumerate() {
println!("{}: {}", index, fruit);
}

println!();

// 结合 Range
for (i, c) in ('a'..='e').enumerate() {
println!("第 {} 个字母: {}", i + 1, c);
}
}

6.4 迭代器适配器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// filter:筛选
println!("偶数:");
for n in numbers.iter().filter(|&&x| x % 2 == 0) {
print!("{} ", n);
}
println!();

// map:映射
println!("平方:");
for n in numbers.iter().map(|&x| x * x) {
print!("{} ", n);
}
println!();

// zip:配对
let names = vec!["Alice", "Bob", "Charlie"];
let scores = vec![95, 87, 92];

println!("\n成绩单:");
for (name, score) in names.iter().zip(scores.iter()) {
println!(" {}: {} 分", name, score);
}

// chain:连接
let first = vec![1, 2, 3];
let second = vec![4, 5, 6];
print!("chain: ");
for n in first.iter().chain(second.iter()) {
print!("{} ", n);
}
println!();

// take 和 skip
print!("skip(2).take(3): ");
for n in numbers.iter().skip(2).take(3) {
print!("{} ", n); // 3 4 5
}
println!();

// windows:滑动窗口
let data = [1, 2, 3, 4, 5];
println!("滑动窗口(3):");
for window in data.windows(3) {
println!(" {:?}", window);
}

// chunks:分块
println!("分块(2):");
for chunk in data.chunks(2) {
println!(" {:?}", chunk);
}
}

7. break 与 continue

7.1 基本 break 和 continue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
// ========== break:退出循环 ==========
println!("=== break 示例 ===");
for i in 0..10 {
if i == 5 {
println!("在 {} 处退出", i);
break;
}
print!("{} ", i);
}
println!();

// ========== continue:跳过当前迭代 ==========
println!("\n=== continue 示例 ===");
for i in 0..10 {
if i % 3 == 0 {
continue; // 跳过 3 的倍数
}
print!("{} ", i);
}
println!();
}

7.2 带标签的 break 和 continue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
fn main() {
// ========== 标签 break ==========
println!("=== 标签 break ===");

'outer: for i in 0..5 {
for j in 0..5 {
if i + j > 4 {
println!("在 i={}, j={} 时退出外层循环", i, j);
break 'outer;
}
print!("({},{}) ", i, j);
}
println!();
}
println!();

// ========== 标签 continue ==========
println!("\n=== 标签 continue ===");

'outer: for i in 0..4 {
for j in 0..4 {
if j == 2 {
continue 'outer; // 跳到外层循环的下一次迭代
}
print!("({},{}) ", i, j);
}
println!(); // 由于 continue 'outer,这行不会执行
}
println!();

// ========== 实际应用:搜索二维数据 ==========
println!("\n=== 搜索二维数组 ===");
let matrix = vec![
vec![1, 2, 3],
vec![4, 5, 6],
vec![7, 8, 9],
];
let target = 5;

'search: for (i, row) in matrix.iter().enumerate() {
for (j, &value) in row.iter().enumerate() {
if value == target {
println!("找到 {} 在位置 [{}, {}]", target, i, j);
break 'search;
}
}
}
}

8. match 表达式

match 是 Rust 中最强大的控制流构造之一。

8.1 基本模式匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
let number = 3;

// match 表达式
match number {
1 => println!("一"),
2 => println!("二"),
3 => println!("三"),
4 | 5 => println!("四或五"), // 使用 | 匹配多个值
6..=9 => println!("六到九"), // 范围匹配
_ => println!("其他"), // _ 是通配符,匹配所有未列出的值
}

// match 作为表达式返回值
let text = match number {
1 => "one",
2 => "two",
3 => "three",
_ => "other",
};
println!("number {} = {}", number, text);
}

8.2 匹配枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#[derive(Debug)]
enum Direction {
Up,
Down,
Left,
Right,
}

#[derive(Debug)]
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
Color(u8, u8, u8),
}

fn main() {
let dir = Direction::Up;

match dir {
Direction::Up => println!("向上"),
Direction::Down => println!("向下"),
Direction::Left => println!("向左"),
Direction::Right => println!("向右"),
}

let msg = Message::Color(255, 128, 0);

match msg {
Message::Quit => println!("退出"),
Message::Move { x, y } => println!("移动到 ({}, {})", x, y),
Message::Write(text) => println!("写入: {}", text),
Message::Color(r, g, b) => println!("颜色: RGB({}, {}, {})", r, g, b),
}
}

8.3 匹配 Option

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn main() {
let some_number: Option<i32> = Some(42);
let no_number: Option<i32> = None;

// 匹配 Option
match some_number {
Some(value) => println!("有值: {}", value),
None => println!("无值"),
}

match no_number {
Some(value) => println!("有值: {}", value),
None => println!("无值"),
}

// 在 match 中使用 Option 做计算
let result = match some_number {
Some(n) if n > 0 => Some(n * 2), // 匹配守卫(guard)
Some(n) => Some(n),
None => None,
};
println!("结果: {:?}", result);
}

8.4 匹配守卫(Guard)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn main() {
let num = Some(4);

match num {
Some(x) if x < 5 => println!("小于5的数: {}", x),
Some(x) if x >= 5 && x < 10 => println!("5到9之间: {}", x),
Some(x) => println!("10及以上: {}", x),
None => println!("无值"),
}

// 匹配守卫的实际应用
let temperature = 25;

let description = match temperature {
t if t < 0 => "极冷",
t if t < 10 => "寒冷",
t if t < 20 => "凉爽",
t if t < 30 => "温暖",
t if t < 35 => "炎热",
_ => "酷热",
};
println!("{}度 -> {}", temperature, description);
}

8.5 绑定与解构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fn main() {
// 绑定值到变量
let x = 5;
let message = match x {
n @ 1..=5 => format!("{} 在 1-5 之间", n),
n @ 6..=10 => format!("{} 在 6-10 之间", n),
n => format!("{} 在其他范围", n),
};
println!("{}", message);

// 解构元组
let point = (3, -5);
match point {
(0, 0) => println!("原点"),
(x, 0) => println!("x 轴上: x={}", x),
(0, y) => println!("y 轴上: y={}", y),
(x, y) if x > 0 && y > 0 => println!("第一象限: ({}, {})", x, y),
(x, y) if x < 0 && y > 0 => println!("第二象限: ({}, {})", x, y),
(x, y) if x < 0 && y < 0 => println!("第三象限: ({}, {})", x, y),
(x, y) => println!("第四象限: ({}, {})", x, y),
}

// 解构结构体
struct Point {
x: i32,
y: i32,
}

let p = Point { x: 5, y: 10 };
match p {
Point { x: 0, y: 0 } => println!("原点"),
Point { x, y: 0 } => println!("x 轴: x={}", x),
Point { x: 0, y } => println!("y 轴: y={}", y),
Point { x, y } => println!("点: ({}, {})", x, y),
}

// 解构引用
let reference = &42;
match reference {
&val => println!("解构引用: {}", val),
}
// 或者
match *reference {
val => println!("解引用: {}", val),
}
}

8.6 match 的穷举性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
fn main() {
// Rust 要求 match 必须穷举所有可能的值

let boolean = true;

// 必须处理 true 和 false 两种情况
let binary = match boolean {
false => 0,
true => 1,
};
println!("boolean as binary: {}", binary);

// 使用 _ 处理剩余所有情况
let number = 13u32;
let description = match number {
0 => "零",
1 => "一",
2..=9 => "个位数",
10..=99 => "两位数",
_ => "大数字", // 不能省略!
};
println!("{}: {}", number, description);

// enum 必须匹配所有变体
enum Color {
Red,
Green,
Blue,
}

let color = Color::Green;
match color {
Color::Red => println!("红"),
Color::Green => println!("绿"),
Color::Blue => println!("蓝"),
// 如果少一个变体,编译器会报错:
// error[E0004]: non-exhaustive patterns: `Blue` not covered
}
}

9. 运算符

9.1 算术运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
fn main() {
let a = 10;
let b = 3;

println!("=== 算术运算符 ===");
println!("{} + {} = {}", a, b, a + b); // 加法:13
println!("{} - {} = {}", a, b, a - b); // 减法:7
println!("{} * {} = {}", a, b, a * b); // 乘法:30
println!("{} / {} = {}", a, b, a / b); // 整数除法:3
println!("{} % {} = {}", a, b, a % b); // 取余:1

// 浮点除法
let c = 10.0_f64;
let d = 3.0_f64;
println!("{} / {} = {}", c, d, c / d); // 浮点除法:3.3333...

// 注意:不同类型不能直接运算
// let result = a + c; // 编译错误!i32 和 f64 不能相加
let result = a as f64 + c; // 需要显式转换
println!("混合运算: {}", result);

// 负数
let neg = -a;
println!("-{} = {}", a, neg);
}

9.2 比较运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
fn main() {
let a = 5;
let b = 10;

println!("=== 比较运算符 ===");
println!("{} == {} : {}", a, b, a == b); // 等于:false
println!("{} != {} : {}", a, b, a != b); // 不等于:true
println!("{} > {} : {}", a, b, a > b); // 大于:false
println!("{} < {} : {}", a, b, a < b); // 小于:true
println!("{} >= {} : {}", a, b, a >= b); // 大于等于:false
println!("{} <= {} : {}", a, b, a <= b); // 小于等于:true

// 字符串比较(按字典序)
let s1 = "apple";
let s2 = "banana";
println!("\"{}\" < \"{}\" : {}", s1, s2, s1 < s2); // true

// 字符比较
println!("'a' < 'z' : {}", 'a' < 'z'); // true

// 注意:不同类型不能直接比较
// println!("{}", 5_i32 == 5_i64); // 编译错误!
println!("跨类型比较: {}", 5_i32 as i64 == 5_i64); // true
}

9.3 逻辑运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
fn main() {
let t = true;
let f = false;

println!("=== 逻辑运算符 ===");
println!("true && true = {}", t && t); // 逻辑与:true
println!("true && false = {}", t && f); // false
println!("false && true = {}", f && t); // false
println!("false && false = {}", f && f); // false

println!();
println!("true || true = {}", t || t); // 逻辑或:true
println!("true || false = {}", t || f); // true
println!("false || true = {}", f || t); // true
println!("false || false = {}", f || f); // false

println!();
println!("!true = {}", !t); // 逻辑非:false
println!("!false = {}", !f); // true

// 短路求值
let x = 0;
// && 短路:如果左边为 false,右边不会执行
if x != 0 && 10 / x > 2 {
println!("这不会执行");
} else {
println!("短路避免了除零错误");
}

// || 短路:如果左边为 true,右边不会执行
let default_name = true;
let name = if default_name || expensive_check() {
"默认名称"
} else {
"其他名称"
};
println!("名称: {}", name);
}

fn expensive_check() -> bool {
println!("这个函数不会被调用(短路求值)");
false
}

9.4 位运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
fn main() {
let a: u8 = 0b1010_1010; // 170
let b: u8 = 0b1100_1100; // 204

println!("=== 位运算符 ===");
println!("a = {:08b} ({})", a, a);
println!("b = {:08b} ({})", b, b);
println!();

// 按位与 (AND)
println!("a & b = {:08b} ({})", a & b, a & b); // 10001000 (136)

// 按位或 (OR)
println!("a | b = {:08b} ({})", a | b, a | b); // 11101110 (238)

// 按位异或 (XOR)
println!("a ^ b = {:08b} ({})", a ^ b, a ^ b); // 01100110 (102)

// 按位取反 (NOT)
println!("!a = {:08b} ({})", !a, !a); // 01010101 (85)

// 左移
let c: u8 = 0b0000_0001;
println!("\nc = {:08b} ({})", c, c);
println!("c << 1 = {:08b} ({})", c << 1, c << 1); // 00000010 (2)
println!("c << 4 = {:08b} ({})", c << 4, c << 4); // 00010000 (16)

// 右移
let d: u8 = 0b1000_0000;
println!("\nd = {:08b} ({})", d, d);
println!("d >> 1 = {:08b} ({})", d >> 1, d >> 1); // 01000000 (64)
println!("d >> 4 = {:08b} ({})", d >> 4, d >> 4); // 00001000 (8)

// 位运算的实际应用:权限标志
const READ: u8 = 0b0000_0001; // 1
const WRITE: u8 = 0b0000_0010; // 2
const EXECUTE: u8 = 0b0000_0100; // 4

let mut permissions: u8 = 0;

// 设置权限(OR)
permissions |= READ;
permissions |= WRITE;
println!("\n权限: {:03b} (读:{}, 写:{}, 执行:{})",
permissions,
permissions & READ != 0,
permissions & WRITE != 0,
permissions & EXECUTE != 0,
);

// 检查权限(AND)
if permissions & READ != 0 {
println!("有读权限");
}

// 移除权限(AND NOT)
permissions &= !WRITE;
println!("移除写权限后: {:03b}", permissions);

// 切换权限(XOR)
permissions ^= EXECUTE;
println!("切换执行权限: {:03b}", permissions);
}

9.5 赋值运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
fn main() {
println!("=== 赋值运算符 ===");

let mut x = 10;
println!("初始值: x = {}", x);

x += 5; // x = x + 5
println!("x += 5 -> x = {}", x); // 15

x -= 3; // x = x - 3
println!("x -= 3 -> x = {}", x); // 12

x *= 2; // x = x * 2
println!("x *= 2 -> x = {}", x); // 24

x /= 4; // x = x / 4
println!("x /= 4 -> x = {}", x); // 6

x %= 4; // x = x % 4
println!("x %%= 4 -> x = {}", x); // 2

// 位赋值运算符
let mut bits: u8 = 0b1010;
println!("\n初始位: {:04b}", bits);

bits &= 0b1100;
println!("&= 1100: {:04b}", bits); // 1000

bits |= 0b0011;
println!("|= 0011: {:04b}", bits); // 1011

bits ^= 0b1111;
println!("^= 1111: {:04b}", bits); // 0100

bits <<= 1;
println!("<<= 1: {:04b}", bits); // 1000

bits >>= 2;
println!(">>= 2: {:04b}", bits); // 0010
}

9.6 范围运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
println!("=== 范围运算符 ===");

// .. 半开区间 [start, end)
let range = 1..5;
print!("1..5: ");
for i in range {
print!("{} ", i); // 1 2 3 4
}
println!();

// ..= 闭区间 [start, end]
let range_inclusive = 1..=5;
print!("1..=5: ");
for i in range_inclusive {
print!("{} ", i); // 1 2 3 4 5
}
println!();

// 在数组切片中使用
let arr = [0, 1, 2, 3, 4, 5];
println!("arr[1..4] = {:?}", &arr[1..4]); // [1, 2, 3]
println!("arr[1..=4] = {:?}", &arr[1..=4]); // [1, 2, 3, 4]
println!("arr[..3] = {:?}", &arr[..3]); // [0, 1, 2]
println!("arr[3..] = {:?}", &arr[3..]); // [3, 4, 5]
println!("arr[..] = {:?}", &arr[..]); // [0, 1, 2, 3, 4, 5]

// 在 match 中使用范围
let score = 85;
let grade = match score {
90..=100 => "A",
80..=89 => "B",
70..=79 => "C",
60..=69 => "D",
0..=59 => "F",
_ => "无效分数",
};
println!("{} 分 -> {} 等级", score, grade);

// Range 作为类型
let r: std::ops::Range<i32> = 0..10;
println!("Range: {:?}", r);
println!("包含 5: {}", r.contains(&5));
println!("长度: {}", r.len());

// 字符范围
print!("字符范围 'A'..='Z': ");
for c in 'A'..='F' {
print!("{} ", c);
}
println!();
}

总结

本章我们学习了 Rust 的控制流程:

  1. if/else 表达式:条件必须是 bool,if 是表达式可以返回值
  2. if let 表达式:简洁的模式匹配,适合只关心一种情况
  3. loop 循环:无限循环,支持 break 返回值和标签
  4. while 循环:条件循环
  5. while let 循环:模式匹配循环
  6. for 循环:最常用的循环,配合 Range 和迭代器
  7. break/continue:支持标签在嵌套循环中使用
  8. match 表达式:强大的模式匹配,要求穷举
  9. 运算符:算术、比较、逻辑、位运算、赋值、范围

下一章我们将学习函数与闭包。