闭包与递归
> 学习闭包(Closure)的语法与捕获环境的能力,以及递归函数的编写方式。
闭包作为函数参数
rust
▶ Runfn main() {
// 定义一些操作
let numbers = vec![1, 2, 3, 4, 5];
// 传递闭包
let doubled = transform(&numbers, |x| x * 2);
println!("翻倍:{:?}", doubled);
let squared = transform(&numbers, |x| x * x);
println!("平方:{:?}", squared);
// 传递普通函数
fn add_ten(x: &i32) -> i32 {
x + 10
}
let added = transform(&numbers, add_ten);
println!("加 10: {:?}", added);
}
// 接受闭包作为参数
fn transform(numbers: &[i32], operation: impl Fn(&i32) -> i32) -> Vec<i32> {
numbers.iter().map(operation).collect()
}递归函数
基础递归
rust
▶ Run// 计算阶乘
fn factorial(n: u64) -> u64 {
match n {
0 | 1 => 1,
_ => n * factorial(n - 1),
}
}
fn main() {
println!("5! = {}", factorial(5)); // 120
println!("10! = {}", factorial(10)); // 3628800
}尾递归优化
rust
▶ Run// 普通递归(可能栈溢出)
fn sum_recursive(n: u64) -> u64 {
if n == 0 {
0
} else {
n + sum_recursive(n - 1)
}
}
// 尾递归(编译器优化)
fn sum_tail_recursive(n: u64, acc: u64) -> u64 {
if n == 0 {
acc
} else {
sum_tail_recursive(n - 1, acc + n)
}
}
fn main() {
println!("1 到 100 的和:{}", sum_tail_recursive(100, 0));
}小结
- 闭包语法:
|参数| 表达式或|参数| { 语句块 } - 闭包可以捕获外部环境中的变量(借用或转移)
- 递归函数必须有明确的终止条件,否则栈溢出
- 递归可以用迭代重写,通常迭代性能更好
练习题
详见:练习题