Part 4 · 进阶篇 —— 释放 Rust 的真正威力
本篇覆盖 第 17 ~ 23 章:闭包与迭代器、智能指针、并发、异步、unsafe 与 FFI、宏系统、Cargo 深入。这是从“会写 Rust”到“精通 Rust”的分水岭。
第 17 章 闭包与迭代器
17.1 闭包(Closure):能捕获环境的匿名函数
fn main() {
let factor = 3;
// 闭包:|参数| 表达式,能捕获外部变量 factor
let multiply = |x: i32| x * factor;
println!("{}", multiply(5)); // 15
// 类型可推断,也可显式标注
let add = |a: i32, b: i32| -> i32 {
a + b };
println!("{}", add(2, 3)); // 5
// 多行闭包用花括号
let describe = |x: i32| {
let doubled = x * 2;
format!("{x} 的两倍是 {doubled}")
};
println!("{}", describe(4));
}
17.2 闭包如何捕获环境:三种方式
闭包会根据你对捕获变量的使用方式,自动选择捕获策略,对应三个 trait:
| Trait | 捕获方式 | 触发条件 | 类比 |
|---|---|---|---|
Fn |
不可变借用 &T |
只读捕获的变量 | 借来看 |
FnMut |
可变借用 &mut T |
修改捕获的变量 | 借来改 |
FnOnce |
获取所有权 T |
消耗捕获的变量(如 move 走) | 借走不还 |
每个闭包同时实现它所需的最小 trait:
FnOnce⊃FnMut⊃Fn(Fn 一定也是 FnMut 和 FnOnce)。
fn main() {
let list = vec![1, 2, 3];
// Fn:只读借用
let only_read = || println!("{:?}", list);
only_read();
println!("{:?}", list); // list 仍可用
// FnMut:可变借用
let mut count = 0;
let mut increment = || {
count += 1; };
increment();
increment();
println!("count = {count}"); // 2
// FnOnce:消耗所有权
let owned = String::from("bye");
let consume = move || println!("{owned}"); // move 强制夺取所有权
consume();
// consume(); // ❌ 若闭包是 FnOnce,只能调用一次
}
move 关键字:强制闭包获取捕获变量的所有权(而非借用)。在把闭包传到别的线程、或让它活得比当前作用域久时必需(第 19 章并发大量使用)。
17.3 闭包作为参数与返回值
// 接收闭包作参数
fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
f(x)
}
// 返回闭包:必须用 impl Fn 或 Box<dyn Fn>(因为闭包类型匿名)
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
move |y| x + y // move 捕获 x
}
fn main() {
println!("{}", apply(|n| n * 2, 10)); // 20
let add5 = make_adder(5);
println!("{}", add5(3)); // 8
}
17.4 迭代器(Iterator):Rust 的函数式核心
迭代器是 Rust 处理集合的惯用方式,惰性求值、零成本、链式优雅。
fn main() {
let v = vec![1, 2, 3, 4, 5];
// 创建迭代器的三种方式
let _borrow = v.iter(); // 迭代 &T(不可变借用)
let _mut = v.iter_mut(); // 迭代 &mut T(可变借用)
let _owned = v.into_iter(); // 迭代 T(获取所有权,消耗 v)
// 惰性:不消费就不执行
let iter = v.iter().map(|x| x * 2); // 此时还没计算
// 消费适配器(触发计算,返回单一值)
let sum: i32 = v.iter().sum();
let collected: Vec<i32> = v.iter().map(|x| x * 2).collect();
let count = v.iter().count();
println!("sum={sum}, count={count}, doubled={collected:?}");
}
17.5 迭代器适配器大全(必背)
let nums = vec![1, 2, 3, 4, 5, 6];
// map:转换每个元素
let doubled: Vec<i32> = nums.iter().map(|x| x * 2).collect();
// filter:过滤
let evens: Vec<&i32> = nums.iter().filter(|x| *x % 2 == 0).collect();
// filter_map:过滤 + 转换(处理 Option)
let words = vec!["1", "two", "3"];
let parsed: Vec<i32> = words.iter()
.filter_map(|s| s.parse::<i32>().ok())
.collect(); // [1, 3]
// fold:累积(reduce 的通用版)
let product = nums.iter().fold(1, |acc, x| acc * x); // 720
// reduce:fold 的简化(用第一个元素作初值)
let sum = nums.iter().copied().reduce(|a, b| a + b); // Some(21)
// enumerate:带索引
for (i, x) in nums.iter().enumerate() {
print!("{i}:{x} ");
}
// zip:并行迭代两个集合
let a = vec![1, 2, 3];
let b = vec!["one", "two", "three"];
let pairs: Vec<_> = a.iter().zip(b.iter()).collect();
// take / skip
let first3: Vec<&i32> = nums.iter().take(3).collect();
let after2: Vec<&i32> = nums.iter().skip(2).collect();
// chain:串联
let all: Vec
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/canfeit/article/details/170147808




