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,因为所有闭包都能被调用。一个会将捕获的值移出闭包体的闭包只实现FnOnce
trait,这是因为它只能被调用一次。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)); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署