1. #[derive(Debug)]
  2. struct Shoe {
  3. size: u32,
  4. style: String,
  5. }
  6. fn find_suitable(data: &Vec<Shoe>, test_fn: fn(&Shoe) -> bool) -> Vec<&Shoe> {
  7. let mut res= vec![];
  8. for s in data.iter() {
  9. if test_fn(s) {
  10. res.push(s);
  11. }
  12. }
  13. res
  14. }
  15. fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
  16. shoes.into_iter()
  17. .filter(move |s| s.size == shoe_size)
  18. .collect()
  19. }
  20. fn main() {
  21. let shoes = vec![
  22. Shoe {size: 10, style: String::from("aaa")},
  23. Shoe {size: 13, style: String::from("bbb")},
  24. ];
  25. let res = find_suitable(&shoes, |s| {s.size > 5});
  26. println!("res {:?}", res);
  27. }

capture environment

clousure 的作用可以capture enclose函数的变量,有几种capture的方式

move

将变量move到闭包函数中,对应的是 FnOnce

  1. fn move_capture() {
  2. let x = vec![1,2,3];
  3. let equal_to_x = move |z| x == z;
  4. // println!("{:?}", x); this won't compile as x has been moved
  5. let y = vec![1,2,3];
  6. assert_eq!(equal_to_x(y), true);
  7. }

borrow mut

&mut || {} 表示mutable borrow 了 clousure中用到的变量,x, 所以当mutate_x 执行后,任然可以使用x,因为x是 被borrow进了clousure中。

  1. fn mutate_capture() -> Vec<i32> {
  2. let mut x = vec![1, 2, 3];
  3. let mutate_x = &mut |z| x.iter_mut().for_each(|y| *y = *y + z);
  4. mutate_x(1);
  5. println!("{:?}", x);
  6. x
  7. }

clousure as return type

  1. fn create_fn() -> impl Fn() {
  2. let text = "Fn".to_string();
  3. move || println!("this is a {}", text);
  4. }

必须使用 move 关键字,表明clousure补货的变量都是by value,因为当函数结束后,text将会被drop