范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

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类型,已经确定了,后面再传浮点数时就会报错。

VIVOOPPO成功注册蓝厂绿厂商标,小米痛失粮厂商标?被外界称为蓝绿兄弟的OPPO和VIVO,脱胎于90年代显赫一时的电子企业步步高,蓝色的VIVO是弟,创立于2009年,绿色的OPPO是兄,成立于2004年。OPPO和VIVO师出同卡西欧赛博制霸代言人王一博2021CITYBATTLE主题系列以城市场景融合虚拟现实和赛博朋克(Cyberpunk)美学,打造雨雾霓虹光影和城市肌理呈现具有科幻质感的全新产品。此系列由GSHOCK品牌代言人币圈那些事HACHIKOINUCEOMichal利用区块链技术使用户能在交易中受益据官方消息,11月19日HACHIKOINUCEOMichal做客XT直播间,与XTAMA专栏主持人Joyc字节跳动上线公益平台据字节跳动公益官方消息,字节跳动公益平台今日正式在抖音今日头条西瓜视频上线。根据规定,具有公开募捐资格的慈善组织可以在字节跳动公益平台上发起募捐,用户可以通过以上产品参与公益项目,小米12X再曝光骁龙8706。28英寸小屏67W,手感媲美小米611月19日,小米新机L3A通过了海外认证,海外版名字为小米12X。这款新机就是大家期待已久的小屏旗舰,国内版可能会启用小米12mini的名字。该机搭载骁龙870处理器,拥有6。2利用摄影修图软件Snapseed的局部工具,可以修出哪些漂亮的效果?利用摄影修图软件Snapseed的局部工具,可以修出哪些漂亮的效果?在众多摄影修图软件中,Snapseed是我常用的一个。这个软件中的工具有很多,可以实现很多效果。今天来为朋友们介三星GalaxyZFlip35G奥运纪念版上架,售价7999元IT之家1月4日消息,三星GalaxyZFlip35G奥运纪念版近日上架了三星商城,采用北京2022冬奥特别冬梦白配色。三星GalaxyZFlip35G奥运纪念版采用了金色和白色搭央视回应45岁程序员找不到工作央视网评论回应了45岁程序员找不到工作的话题,中心思想大概是,个人将低预期及企业提供更多职位。评论里有一句话我非常认同有的行业越老越吃香,有的行业吃的是青春饭,谁也无法两头吃。每个为什么在日本是实体店干掉电商,在中国却是电商干掉实体?我的看法是,一方面从我们国内角度看我国电商比实体经济做得好,更深层次是因为政策。电商兴起前,我国处于世界工厂的初级阶段,生产采购经营环境污染,处处被外资企业把控牵着鼻子走,我们建工不想多花钱还想拥有全能体验,iPhone13的平替款出现,只需3699元很多人之所以想要入手iPhone13,并不是因为多么喜欢苹果这个品牌,从消费者的角度出发,出色的体验才是关键。所以如果国产手机也能让消费者拥有更流畅的体验,并且价格更便宜,试问谁还复盘知网侵权案没有损失的侵权丨蔚言大义傅蔚冈文一hr知网再一次成为媒体关注的焦点,这次是因为法院的一起判决。据报道,89岁的中南财经政法大学退休教授赵德馨因百篇论文被中国知网擅自收录,以诉讼方式维权获赔70余万元。70
大数据编程入门Java集合框架在Java里面有一些特设类,非常有用,但它们缺少一个核心,统一的主体,于是需要一个符合要求的集合框架,今天小编将为大家带来了大数据编程入门Java集合框架。一Java集合框架的概念大数据编程入门Java泛型在Java集合中的元素通过对类型Object的引用来实现参数的任意化,任意化带来的缺点是要作显示的强制类转换,对于强制类型转换错误的情况下,编译器可能不提示错误,在运行时才显示异常大数据编程入门JavaLinkedList在Java中,LinkedList和ArrayList一样都是属于集合List的实现类,今天小编将为大家带来大数据编程入门JavaLinkedList这篇文章来介绍LinkedLi47的新中产不再买房,把目光投向这两个方向文巴九灵过去一年,55的新中产家庭财富增幅在10以上。家底变厚的同时,新中产的投资却趋于保守和谨慎。其中,56的新中产增加了储蓄。2021年拥有50万以上投资资金的新中产占比跟20天下第一村华西村,会因挤兑破产吗?见过各种暴雷,没见过一个村子也会暴雷。见过各种村子,没见过哪个村子修酒店修机场修长城,甚至天安门广场都仿了一个。300多米高的五星级酒店里还放了个一吨重的金牛,比华尔街都壕,华尔街微众银行踩雷记蛋壳事件之后,最近的微众银行正在节节败退。微众银行是一家互联网银行,而互联网顾名思义,就是没有线下的营业厅以及团队,业务主要在互联网上进行。但金融这事又比较特殊,除了大额的企业贷或法学精英海外带100多份药毒死百亿游族老总,什么仇什么怨?最近游族的事情沸沸扬扬,我一个不打游戏的人,现在都知道游族都出了哪些游戏了。游族几个公告看下来,就发现一点,上市公司的话不可信。每次辟谣跟造谣一样,还是官方的,以后股民们要注意了。每四个高考生,就有一个复读生,太卷了今天高考第一天,祝所有的考生都能考好。不过显然这是不可能,升学率固定,怎么都会是有人欢喜有人忧,考差的就面临着回家进厂职业教育以及复读。复读生到底有多少,没人真的统计,但从高考生数按摩靠垫好用吗?奥佳华荣泰傲胜三款明星产品评测给你答案随着人们健康意识的提高,越来越多人开始喜欢按摩,但常去按摩店不太方便,买按摩椅倒是一劳永逸,但如果家里面积小,就难以容纳。考虑下一线城市的平均房价,动辄小10万,一台按摩椅平均要占西门子收购Supplyframe,加快数字市场战略进程西门子近期签署了一份收购协议,将以7亿美元收购全球电子价值链中领先的致力于提供从设计到采购信息平台的Supplyframe公司。该交易将为Supplyframe和西门子的客户带来巨价格腰斩到每斤23。8元苏宁超市年货节车厘子抢疯了车厘子有多贵?以前我们都说财务自由,但后来却发现即便是财务自由,面对动辄40元斤的车厘子还是下不去狠手购买,为了逞口舌之欲花费这么大的价钱似乎有些不太值得。而且,那些打着智力进口的