====== 闭包、迭代器与模块系统 ====== ===== 闭包(Closure) ===== 闭包是可以捕获环境的匿名函数。 ==== 闭包语法 ==== fn main() { // 完整语法 let add_one = |x: i32| -> i32 { x + 1 }; // 简写(省略类型注解) let add_two = |x| x + 2; // 多行闭包 let multiply = |x, y| { let result = x * y; println!("{} x {} = {}", x, y, result); result }; println!("{}", add_one(5)); // 6 println!("{}", add_two(5)); // 7 println!("{}", multiply(3, 4)); // 12 } ==== 捕获环境 ==== 闭包可以捕获其定义作用域中的变量: fn main() { let x = 4; let equal_to_x = |z| z == x; // 捕获 x println!("{}", equal_to_x(4)); // true } ==== 闭包捕获方式 ==== 闭包通过三种方式捕获变量: * ''FnOnce'' - 取得所有权,只能调用一次 * ''FnMut'' - 可变借用 * ''Fn'' - 不可变借用 fn main() { let s = String::from("hello"); // Fn:不可变借用 let print = || println!("{}", s); print(); println!("仍可用: {}", s); // OK // FnMut:可变借用 let mut s2 = String::from("hello"); let mut append = || s2.push_str(" world"); append(); // FnOnce:取得所有权 let s3 = String::from("hello"); let consume = || drop(s3); consume(); // println!("{}", s3); // 编译错误:s3 已被移动 } ==== 闭包作为参数 ==== fn do_twice(f: F, x: i32) -> i32 where F: Fn(i32) -> i32, { f(x) + f(x) } fn main() { let result = do_twice(|x| x * 2, 5); println!("{}", result); // 20 (10 + 10) } ===== 迭代器(Iterator) ===== 迭代器是 Rust 中处理序列的强大工具。 ==== 基本使用 ==== fn main() { let v = vec![1, 2, 3, 4, 5]; // for 循环隐式使用迭代器 for i in &v { println!("{}", i); } // 显式创建迭代器 let iter = v.iter(); // 不可变引用迭代器 for i in iter { println!("{}", i); } } ==== 消耗型适配器 ==== 消耗迭代器的方法: fn main() { let v = vec![1, 2, 3, 4, 5]; // sum - 求和 let sum: i32 = v.iter().sum(); println!("{}", sum); // 15 // count - 计数 let count = v.iter().count(); println!("{}", count); // 5 // collect - 收集到集合 let doubled: Vec = v.iter().map(|x| x * 2).collect(); println!("{:?}", doubled); // [2, 4, 6, 8, 10] } ==== 迭代器适配器 ==== 链式调用来转换迭代器: fn main() { let v = vec![1, 2, 3, 4, 5, 6]; // map - 映射每个元素 // filter - 过滤元素 // take - 取前 n 个 let result: Vec = v.iter() .map(|x| x * 2) // 全部乘以 2 .filter(|x| x % 3 == 0) // 保留 3 的倍数 .take(3) // 取前 3 个 .collect(); println!("{:?}", result); // [6, 12] // 链式计算:过滤出偶数,平方,求和 let sum: i32 = (1..=10) .filter(|x| x % 2 == 0) .map(|x| x * x) .sum(); println!("{}", sum); // 2^2 + 4^2 + 6^2 + 8^2 + 10^2 = 220 } ==== 自定义迭代器 ==== struct Counter { count: u32, } impl Counter { fn new() -> Counter { Counter { count: 0 } } } impl Iterator for Counter { type Item = u32; fn next(&mut self) -> Option { self.count += 1; if self.count <= 5 { Some(self.count) } else { None } } } fn main() { let sum: u32 = Counter::new() .zip(Counter::new().skip(1)) .map(|(a, b)| a * b) .filter(|x| x % 3 == 0) .sum(); println!("{}", sum); } ===== 模块系统 ===== ==== crate 和模块 ==== Rust 的组织单元: * **crate** - 一个库或可执行项目的根 * **模块(mod)** - 组织代码的层级结构 // src/main.rs mod front_of_house; fn main() { front_of_house::hosting::add_to_waitlist(); } // src/front_of_house.rs(或 src/front_of_house/mod.rs) pub mod hosting { pub fn add_to_waitlist() { println!("已添加候补"); } } ==== 路径引用 ==== mod restaurant { pub mod hosting { pub fn add_to_waitlist() {} fn seat_at_table() {} // 默认私有 } mod serving { fn take_order() {} } } fn main() { // 绝对路径 crate::restaurant::hosting::add_to_waitlist(); // 相对路径 use restaurant::hosting; hosting::add_to_waitlist(); } ==== use 关键字 ==== use std::collections::{HashMap, HashSet}; // 嵌套导入 use std::io::{self, Write}; // self 表示模块本身 use std::fmt::Result; // 导入到当前作用域 // 重命名 use std::collections::HashMap as Map; fn main() { let mut map = HashMap::new(); map.insert(1, 2); let mut map2 = Map::new(); map2.insert("a", "b"); } ==== 模块可见性 ==== ^ 修饰符 ^ 可见性 ^ | ''pub'' | 公开可见 | | (无修饰) | 私有,仅当前模块及其子模块可见 | | ''pub(crate)'' | 整个 crate 内可见 | | ''pub(super)'' | 上一级模块可见 | | ''pub(in path)'' | 指定路径可见 | pub fn public_func() {} fn private_func() {} pub(crate) fn crate_visible() {} pub(super) fn parent_visible() {} ==== 外部依赖 ==== 在 ''Cargo.toml'' 中添加: [dependencies] serde = { version = "1.0", features = ["derive"] } rand = "0.8" 在代码中使用: use rand::Rng; use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize)] struct User { name: String, age: u8, } fn main() { let secret_number = rand::thread_rng().gen_range(1..=100); println!("随机数: {}", secret_number); } ===== 本章小结 ===== * 闭包是捕获环境的匿名函数,三种捕获方式:''Fn''、''FnMut''、''FnOnce'' * 迭代器提供 lazy 的序列操作,适配器可链式调用 * ''collect()''、''map()''、''filter()'' 等是常用迭代器方法 * 模块系统组织代码:''mod''、''use''、''pub'' * 使用 ''pub'' 控制可见性 * ''Cargo.toml'' 管理外部依赖