Rust学习笔记(三十八)闭包(上)
什么是闭包
可以捕获其所在环境的匿名函数叫做闭包。有4个特点: 是匿名函数 可以将其保存为变量并作为函数的参数 可以在一个地方创建闭包,然后在另一个上下文中调用闭包来完成运算 可以从其定义的作用域捕获值 例子:生成自定义运动计划的程序
本例算法逻辑并不是重点,重点是算法中的计算过程需要几秒钟的时间。而我们的目标是不发生不必要的等待。即仅在必要时调用算法,而且只调用一次。 //src/main.rs use std::{thread, time::Duration}; fn main() { let sumulated_user_specified_value = 10; let simulated_random_number = 7; generate_workout(sumulated_user_specified_value, simulated_random_number); } fn simulated_expensive_calculation(intensity: u32) -> u32 { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2));//sleep模拟等待时间 intensity } fn generate_workout(intensity: u32, random_number: u32) { if intensity < 25 {//运动强度小于25时,调用两次耗时算法生成两个运动计划 println!( "Today, do {} pushups!", simulated_expensive_calculation(intensity) );//做一定时间的俯卧撑 println!( "Next, do {} situps!", simulated_expensive_calculation(intensity) );//做一定时间的仰卧起坐 } else {//大于等于25时,又分两种情况 if random_number == 3 {//随机数为3时,休息,不调用耗时算法 println!("Take a break today! Remember to stay hydrated!"); } else {//否则调用耗时算法,生成跑步计划 println!( "Today, run for {} minutes!", simulated_expensive_calculation(intensity) ); } } }
根据以上代码的逻辑,耗时方法最多执行2次。不符合我们的目标。我们可以做以下修改: //src/main.rs fn generate_workout(intensity: u32, random_number: u32) { let expensive_result = simulated_expensive_calculation(intensity); if intensity < 25 { println!("Today, do {} pushups!", expensive_result); println!("Next, do {} situps!", expensive_result); } else { if random_number == 3 { println!("Take a break today! Remember to stay hydrated!"); } else { println!("Today, run for {} minutes!", expensive_result); } } }
此时无论哪种情况,耗时代码只会运行一次。但是当intensity >= 25并且random_number == 3时,并没有用到耗时方法的返回值,所以在此情况下会造成一次不必要的执行。 这里的最佳方案是:只有在需要耗时方法的返回值时,才会调用它。可以使用闭包来实现: //src/main.rs fn generate_workout(intensity: u32, random_number: u32) { //只是定义闭包(匿名函数),而不执行,只有它后跟着()时才会执行 let expensive_closure = |num| { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); num }; if intensity < 25 { //使用expensive_closure(intensity)闭包 println!("Today, do {} pushups!", expensive_closure(intensity)); println!("Next, do {} situps!", expensive_closure(intensity)); } else { if random_number == 3 { println!("Take a break today! Remember to stay hydrated!"); } else { println!("Today, run for {} minutes!", expensive_closure(intensity)); } } }
但是这里当intensity < 25时,闭包依然被调用了两次。可以将expensive_closure(intensity)的值绑定到一个变量上存起来,然后使用。但是我们不这样解决,后面再看具体实现。 闭包的类型推断
闭包不强制要求标注参数和返回值类型,这一点与函数不同。因为函数是暴露给用户的接口,我们严格定义函数的参数和返回值类型,有利于用户的理解和使用。但是闭包并不用于暴露给用户,不用命名他们或暴露给库的用户调用。 闭包通常很短小,通常只是在狭小的上下文中工作,编译器能推断出其类型。 当然也可以手动标注类型,例: let expensive_closure = |num: u32| -> u32 { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); num }; 函数和闭包的定义语法比较
函数:fn add_one_v1(x: u32) -> u32 {x + 1} 闭包:let add_one_v2 = |x: u32| -> u32 {x + 1} 闭包:let add_one_v3 = |x| {x + 1} 闭包:let add_one_v4 = |x| -> x + 1匿名函数体只有一句时,可省略{} 闭包的类型推断
注意:闭包的定义最终只会为参数/返回值推断出唯一具体的类型,例: fn main() { let example_closure = |x| x; let s = example_closure(1); let n = example_closure(1.1); }
此时就会报错,因为第一次使用时,编译器已经推断出参数与返回值是i32类型,已经确定了,后面再传浮点数时就会报错。
大数据编程入门Java集合框架在Java里面有一些特设类,非常有用,但它们缺少一个核心,统一的主体,于是需要一个符合要求的集合框架,今天小编将为大家带来了大数据编程入门Java集合框架。一Java集合框架的概念
大数据编程入门Java泛型在Java集合中的元素通过对类型Object的引用来实现参数的任意化,任意化带来的缺点是要作显示的强制类转换,对于强制类型转换错误的情况下,编译器可能不提示错误,在运行时才显示异常
大数据编程入门JavaLinkedList在Java中,LinkedList和ArrayList一样都是属于集合List的实现类,今天小编将为大家带来大数据编程入门JavaLinkedList这篇文章来介绍LinkedLi
47的新中产不再买房,把目光投向这两个方向文巴九灵过去一年,55的新中产家庭财富增幅在10以上。家底变厚的同时,新中产的投资却趋于保守和谨慎。其中,56的新中产增加了储蓄。2021年拥有50万以上投资资金的新中产占比跟20
天下第一村华西村,会因挤兑破产吗?见过各种暴雷,没见过一个村子也会暴雷。见过各种村子,没见过哪个村子修酒店修机场修长城,甚至天安门广场都仿了一个。300多米高的五星级酒店里还放了个一吨重的金牛,比华尔街都壕,华尔街
微众银行踩雷记蛋壳事件之后,最近的微众银行正在节节败退。微众银行是一家互联网银行,而互联网顾名思义,就是没有线下的营业厅以及团队,业务主要在互联网上进行。但金融这事又比较特殊,除了大额的企业贷或
法学精英海外带100多份药毒死百亿游族老总,什么仇什么怨?最近游族的事情沸沸扬扬,我一个不打游戏的人,现在都知道游族都出了哪些游戏了。游族几个公告看下来,就发现一点,上市公司的话不可信。每次辟谣跟造谣一样,还是官方的,以后股民们要注意了。
每四个高考生,就有一个复读生,太卷了今天高考第一天,祝所有的考生都能考好。不过显然这是不可能,升学率固定,怎么都会是有人欢喜有人忧,考差的就面临着回家进厂职业教育以及复读。复读生到底有多少,没人真的统计,但从高考生数
按摩靠垫好用吗?奥佳华荣泰傲胜三款明星产品评测给你答案随着人们健康意识的提高,越来越多人开始喜欢按摩,但常去按摩店不太方便,买按摩椅倒是一劳永逸,但如果家里面积小,就难以容纳。考虑下一线城市的平均房价,动辄小10万,一台按摩椅平均要占
西门子收购Supplyframe,加快数字市场战略进程西门子近期签署了一份收购协议,将以7亿美元收购全球电子价值链中领先的致力于提供从设计到采购信息平台的Supplyframe公司。该交易将为Supplyframe和西门子的客户带来巨
价格腰斩到每斤23。8元苏宁超市年货节车厘子抢疯了车厘子有多贵?以前我们都说财务自由,但后来却发现即便是财务自由,面对动辄40元斤的车厘子还是下不去狠手购买,为了逞口舌之欲花费这么大的价钱似乎有些不太值得。而且,那些打着智力进口的