Rust 闭包

闭包

创建闭包

fn main() {
    let use_closure = || {
        println!("Hello, world!");
    };
    use_closure()
}

语法格式

let func = |函数参数| -> 返回值 {逻辑};
let func = |x: u32| -> u32 {x + 1};

let func = |x| x + 1;

// 有点类似lambda

闭包定义会为每个参数和返回值类型推导一个具体的类型,但是不能推导两次。也就是说,如果不写类型签名,调用两次的话,两次的传的值都要是相同类型的。

闭包允许捕获调用者作用域中的值。

3 种获取参数的方式:获取所有权,可变借用,不可变借用。

fn main() {
    let i = 1;
    let use_closure = |x| {
        x + i
    };
    use_closure(1);
}
fn check_environment() {
    let x = 5;
    let check = |z| z == x;
    let y = 5;

    // 检查y是否符合check表达式规则
    assert!(check(y));
}

获取所有权的例子

fn check_environment() {
    let x = vec![1, 2, 3];
    // 移进去所有权到闭包里
    let check = move |z| z == x;

    // 所有权移交了,这里就会报错
    println!("{:?}", x);
    let y = vec![1, 2, 3];

    assert!(check(y))
}

闭包实现单例模式

// 闭包实现单例模式
struct Cacher<T> where T: Fn(u32) -> u32{
    // calcuation泛型被要求接收一个函数
    calcuation: T,
    value: Option<u32>,
}

impl <T> Cacher<T> where T: Fn(u32) -> u32{
    
    fn new(calcuation: T) -> Cacher<T>{
        Cacher{calcuation, value: None,}
    }

    fn check_value(&mut self, arg: u32) -> u32{
        match self.value {
            Some(v) => v,
            None => {
                let new_number = (self.calcuation)(arg);
                // 这里是把Some(new_number)整个
                self.value = Some(new_number);
                println!("{:?}", self.value);
                new_number
            }
        }
    }
}

fn main() {
   let mut info_obj = Cacher::new(|x| x + 1);
   let value = info_obj.check_value(1);
   println!("{}", value);

   let value_next = info_obj.check_value(3);
   println!("{}", value_next);
}

总结

  1. 闭包是可以保存进变量或者作为参数传递给其他函数的匿名函数
  2. 闭包和函数的区别:闭包允许捕获调用者作用域中的值。
posted @ 2021-12-06 15:47  阿初  阅读(127)  评论(0编辑  收藏  举报