Rust基础-关于闭包

简单说说闭包,网上相关知识很多,总结一下。

  • 闭包是干啥的?

答:闭包的主要作用是创建抽象行为

  • 闭包是什么?

答:它是一种匿名函数,可保存为变量,可作为参数,可访问在其定义域的上下文中的值。它应该很短小,编译器通常能推断出其类型

  • 有哪几种闭包?

答:可以有三种类型的闭包,都实现了以下trait之一:
        Fn:不可变借用
        FnMut:可变借用
        FnOnce:取得所有权

另外:move关键字:在参数列表前用了move关键字后,强制闭包取得该参数的所有权。

接下来上代码:

1、闭包当作参数的用法

fn fn_clos(func:F,i:i32) where F:FnOnce(i32)-> i32{
   println!("{}",func(i) );         
}
fn main() {
    let  i1 = 1;
    let  i2 = 2;
    let  clos = |a| {i1+i2+a};
    fn_clos(clos,1);
}

再变个花样:

fn f i8> (mut g:T) {
        println!("{}", g(1));
}
fn main() {
    let  mut i1=1;
    let  i2=2;
    f(|a| {
        i1=i1+a+i2;
        i1
    });
}

 2、闭包和函数签名

fn main() {
    let add = |x, y| x + y;

    let mut x = add(5,7);
    println!("x={}",x);
    type Binop = fn(i32, i32) -> i32;
    let bo: Binop = add;
    x = bo(10,6);
    println!("x={}",x);
}

 3、闭包与Struct,有点像委托。具体解释看注释。

struct NumStruct//定义T的类型为Fn
where T:Fn(String,i8)->i8,
{
    closure:T,
    value : Option,
}

//返回一个NumStruct,并且将闭包传入NumStruct.closure
impl NumStruct where T:Fn(String,i8)->i8, {
    fn invoke_closure(arg_closure:T)->NumStruct{
        NumStruct{
            closure:arg_closure,
            value:None,
        }
    }
    fn double_value (&mut self,arg1:String,arg2:i8)->i8{
        match self.value {
            Some(v)=>v,
            None=>{
                let v=(self.closure)(arg1,arg2);//调用传入的闭包过程,v是结果
                self.value=Some(v);
                v
            }
        }
    }
}
fn main() {

    let hint_string:String=String::from("input value is:");
    let input_value:i8=5;
  
    let mut y=NumStruct::invoke_closure(   //将闭包传入NumStruct
        |a1:String, a2:i8|{
        println!("{}{}",a1,a2);
        a2+a2 
    });
    let result=y.double_value(hint_string,input_value);  
    println!("Double Value={}",result);
}

输出:

 4、闭包的捕获可以通过称为“唯一不可变借用”(unique immutable borrow)的特殊借用进行,这种借用不能在语言中的任何其他地方使用,也不能显式写出。它发生在修改可变引用的referent时,如下例所示:

fn main() {
    let mut b = false;
    let x = &mut b;
    {
        let mut c = || { *x = true; };
        // 下面会报错:
        // let y = &x;
        c();
    }
    let z = &x;
    println!("{}",z);//输出true
    println!("{}",b);//输出true
}

你可能感兴趣的:(rust,rust)