闭包
可以存储在变量中或作为参数传递给其他函数的匿名函数。
闭包中的捕获概念可以理解成从该闭包的上下文获得一些变量的信息以至于可以穿透函数定义的界限使用这些变量。
闭包的类型推断和注释
- 闭包通常不需要像n函数那样标注参数或返回值的类型
- 不会在暴露给用户的接口中使用
- 通常很短,只在有限的上下文中使用,以便编译器可推断其参数和返回值的类型
- 可以添加类型注释
闭包有点类似匿名函数。
例:
1 2 3 4 5 6 7 8 9
| let expensive = |num: u32| -> u32 { num }
let example = |x| x; let s = example(String::from("hello"));
|
捕获引用或移动所有权
不可变借用
1 2 3 4 5 6 7 8 9 10
| fn main() { let list = vec![1, 2, 3]; println!("{list:?}");
let only_borrows = || println!("{list:?}");
println!("{list:?}"); only_borrows(); println!("{list:?}"); }
|
可变借用
1 2 3 4 5 6 7 8 9
| fn main() { let mut list = vec![1, 2, 3]; println!("{list:?}");
let mut borrows_mut = || list.push(7);
borrows_mut(); println!("{list:?}"); }
|
获得所有权
1 2 3 4 5 6 7 8 9 10
| use std::thread;
fn main() { let list = vec![1, 2, 3]; println!("{list:?}");
thread::spawn(move || println!("{list:?}")) .join() .unwrap(); }
|
闭包体可以对捕获的值进行的操作:
- 将捕获的值移出闭包
- 修改捕获的值
- 既不移动也不修改值
- 完全不从环境中捕获值
Iterators
列:
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 v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter { println!("{val}"); }
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
println!("{total}");
let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
println!("{v2:?}"); }
|