Day 4: 函数与控制流
今天是《30天精通Rust语言》系列的第四天。我们将学习Rust中的函数定义和控制流语句。函数是组织代码的基本单元,控制流则决定了程序的执行顺序。
2. 函数定义
Section titled “2. 函数定义”Rust使用 fn 关键字定义函数。函数可以在文件任意位置定义,顺序不影响(不像C语言需要先声明后调用)。
2.1 基本函数定义
Section titled “2.1 基本函数定义”fn greet() { println!("Hello, Rust!");}
fn main() { greet();}2.2 带参数的函数
Section titled “2.2 带参数的函数”函数参数需要标注类型:
fn greet(name: &str) { println!("Hello, {}!", name);}
fn main() { greet("Rust"); greet("World");}2.3 有返回值的函数
Section titled “2.3 有返回值的函数”Rust函数默认返回最后一个表达式的值,或使用 return 关键字显式返回:
fn add(a: i32, b: i32) -> i32 { a + b // 注意:不能加分号,否则变成语句而非表达式}
fn subtract(a: i32, b: i32) -> i32 { return a - b; // 显式返回}
fn main() { let result = add(5, 3); println!("5 + 3 = {}", result);
let result = subtract(10, 4); println!("10 - 4 = {}", result);}重要:Rust中大多数语句不返回值,因此 a + b; 末尾的分号会使函数返回 ()(空元组),而非 a + b 的值。
2.4 多返回值与元组
Section titled “2.4 多返回值与元组”函数可以通过元组返回多个值:
fn min_max(numbers: &[i32]) -> (i32, i32) { let min = numbers.iter().min().unwrap(); let max = numbers.iter().max().unwrap(); (*min, *max)}
fn main() { let nums = [3, 1, 4, 1, 5, 9, 2, 6]; let (min, max) = min_max(&nums); println!("Min: {}, Max: {}", min, max);}3. 控制流:条件分支
Section titled “3. 控制流:条件分支”3.1 if表达式
Section titled “3.1 if表达式”Rust的 if 是表达式,可以有返回值:
fn main() { let number = 7;
if number < 5 { println!("condition was true"); } else if number < 10 { println!("condition was false, but number < 10"); } else { println!("condition was false, and number >= 10"); }}3.2 if-let简化
Section titled “3.2 if-let简化”当只关心一种模式时,if let 提供了更简洁的写法:
fn main() { let some_value: Option<i32> = Some(42);
if let Some(value) = some_value { println!("Got value: {}", value); }}4. 控制流:循环
Section titled “4. 控制流:循环”Rust提供了三种循环结构:loop、while 和 for。
4.1 loop循环
Section titled “4.1 loop循环”loop 是无限循环,需要手动 break 退出:
fn main() { let mut counter = 0;
let result = loop { counter += 1;
if counter == 10 { break counter * 2; // break可以返回值 } };
println!("Result: {}", result); // 输出20}4.2 while循环
Section titled “4.2 while循环”while 循环在条件为真时重复执行:
fn main() { let mut number = 3;
while number != 0 { println!("{}!", number); number -= 1; }
println!("LIFTOFF!!!");}4.3 for循环
Section titled “4.3 for循环”for 循环是最常用的遍历方式,安全且高效:
fn main() { // 遍历范围 for i in 1..=5 { println!("i = {}", i); }
// 遍历数组 let array = [10, 20, 30]; for element in array.iter() { println!("Element: {}", element); }
// 使用.rev()反转范围 for i in (1..=3).rev() { println!("{}!", i); }}5. 实用示例
Section titled “5. 实用示例”让我们编写一个计算阶乘的程序,综合运用函数和循环:
fn factorial(n: u64) -> u64 { if n == 0 { return 1; }
let mut result = 1; for i in 1..=n { result *= i; } result}
fn main() { let nums = [0, 1, 2, 3, 4, 5, 10];
for n in nums { println!("{}! = {}", n, factorial(n)); }}输出:
0! = 11! = 12! = 23! = 64! = 245! = 12010! = 36288006. match模式匹配
Section titled “6. match模式匹配”Rust的 match 是强大的模式匹配结构,类似于其他语言的switch但更强大:
fn main() { let number = 7;
match number { 1 => println!("One"), 2 => println!("Two"), 3 => println!("Three"), 4..=10 => println!("Between 4 and 10"), _ => println!("Something else"), }}match 会穷尽所有可能,因此处理 _ 分支是必要的(类似于default)。
7. 实践练习
Section titled “7. 实践练习”今天的实践任务:
- 编写一个函数
is_even(n: i32) -> bool,判断一个数是否为偶数。 - 编写一个函数
fibonacci(n: u32) -> u32,返回斐波那契数列第n项。 - 编写一个程序,使用循环计算1到100之间所有奇数的和。
- 改写上述斐波那契函数,使用递归实现,对比两种实现的差异。
- 使用
match编写一个简单的石头剪刀布游戏判断逻辑。
8. 常见问题
Section titled “8. 常见问题”问:为什么Rust函数返回值不能加尾部分号?
答:在Rust中,分号结束一个语句,语句返回值是 ()。若要返回表达式的值,该表达式必须是函数的最后一行且不加分的表达式。
问:三种循环应该如何选择?
答:for 循环是最推荐的,适合遍历范围或集合。while 适合在条件为真时重复执行的场景。loop 适合需要手动控制循环退出的场景。
今天我们学习了Rust中的函数定义和控制流语句:
- 函数使用
fn定义,支持参数和返回值。 if是表达式,可以有返回值。- 三种循环:
loop(无限循环)、while(条件循环)、for(遍历循环)。 match提供强大的模式匹配功能。
明天我们将学习Rust最核心的概念:所有权系统。准备好迎接挑战!