rust(6) 闭包
//语法格式 和函数fn 有点像。
fn add_one_v1 (x:i32)->i32 { x+1 }
fn main(){
let add_one_v2 = |x:i32|->i32{ x+1 };
let add_one_v3=|x| {x+1};
let add_one_v4=|x| x+1;
let a=add_one_v1(5);//使用函数加1
let b = add_one_v2(5);
let c = add_one_v3(5);
let d = add_one_v4(5);
//闭包定义会为每个参数和返回值类型推导一个具体的类型,但是,,,不能推导两次,下面的会报错
let example_closure=|x| x;
let e = example_closure(String::from("nihao"));
let f = example_closure(5);
}
一个示例
//实现一个缓存,只处理第一次传入的值,并保存。 fn main(){ let mut c = Cacher::new(|x| x+1); let v1 = c.value(1); let v2 = c.value(100); println!("v1 is {},v2 is {}",v1,v2); } struct Cacher<T> where T:Fn(u32)->u32 { 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 value(&mut self,arg:u32)->u32{ match self.value { Some(v) =>v, None => { let v = (self.calcuation)(arg); self.value=Some(v); v } } } }
闭包可以通过三种方式捕获其环境,它们直接对应到函数获取参数的三种方式:不可变借用,可变借用和获取所有权。闭包会根据函数体中如何使用被捕获的值决定用哪种方式捕获。
FnOnce适用于能被调用一次的闭包,所有闭包都至少实现了这个 trait,因为所有闭包都能被调用。一个会将捕获的值移出闭包体的闭包只实现FnOncetrait,这是因为它只能被调用一次。FnMut适用于不会将捕获的值移出闭包体的闭包,但它可能会修改被捕获的值。这类闭包可以被调用多次。Fn适用于既不将被捕获的值移出闭包体也不修改被捕获的值的闭包,当然也包括不从环境中捕获值的闭包。这类闭包可以被调用多次而不改变它们的环境,这在会多次并发调用闭包的场景中十分重要。
fn main(){ /* let x =4; let equal_to_x = |z| z==x; let y = 4 ; assert!(equal_to_x(y)); */ let x = vec![1,2,3]; let equal_to_x =move |z| z==x; println!("x is {:?}",x);//这里会报错,因为x在上一行已经呗借用了,这里已经失效了。 let y = vec![1,2,3]; assert!(equal_to_x(y)); }
浙公网安备 33010602011771号