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

Rust学习笔记(四十二)迭代器(下)改进命令行项目

  使用Iterator trait创建自定义迭代器
  只需要实现Iterator trait的next方法就可以,例: //src/lib.rs struct Counter {     count: u32, }  impl Counter {     fn new() -> Counter {         Counter { count: 0 }     } }  impl Iterator for Counter {     //此语法后面会学     type Item = u32;      fn next(&mut self) -> Option {         if self.count < 5 {             self.count += 1;             Some(self.count)         } else {             None         }     } }  #[test] fn calling_next_directly() {//能从1迭代到5     let mut counter = Counter::new();     assert_eq!(counter.next(), Some(1));     assert_eq!(counter.next(), Some(2));     assert_eq!(counter.next(), Some(3));     assert_eq!(counter.next(), Some(4));     assert_eq!(counter.next(), Some(5));     assert_eq!(counter.next(), None); }  #[test] fn using_other_iterator_trait_methods() {     let sum: u32 = Counter::new()//新建一个1到5的迭代器     .zip(Counter::new().skip(1))//生成一个跳过1的迭代器(2-5),然后与上面的迭代器生成一个元素是元组的新迭代器(1, 2)(2, 3)(3, 4) (4, 5)     .map(|(a, b)| a * b)//元组两个元素相乘=2,6,12,20     .filter(|x| x % 3 == 0)//留下能被3整除的是6,12     .sum();//求和=18      assert_eq!(sum, 18); } 使用闭包和迭代器改进37节命令行项目
  先找到Rust学习笔记(三十七)命令行项目实例里的代码,这里不给出完整代码 pub struct Config {     pub query: String,     pub filename: String, }  impl Config {     pub fn new(args: &[String]) -> Result {         if args.len() < 3 {             return Err("not enough arguments");         }         let query = args[1].clone();         let filename = args[2].clone();         Ok(Config { query, filename })     } }
  这里由于new函数的参数是一个引用,所以需要clone出要查询的内容和文件名,然后构造Config的实例,这样Config实例才能拥有它俩的所有权。这里我们学习了迭代器,就可以传入一个拥有所有权的迭代器,就不用clone参数了。 //src/main.rs use std::env; use cmd_line::{self, Config};  use std::process; fn main() {     //unwrap_or_else用于Result后,Result是Ok时直接返回Ok内的值。     //Err时执行参数中的闭包,类似于匿名函数,err是参数,{}里是函数体(后面详解)     let config = Config::new(env::args()).unwrap_or_else(|err| {         println!("Problem parsing arguments: {}", err);//打印错误         process::exit(1);//终止程序     });     //使用if let匹配错误情况,当run函数返回Err时会执行{}内逻辑     if let Err(e) = cmd_line::run(config) {       println!("Applocation error: {}", e);//打印错误       process::exit(1);//终止程序     }; } //src/lib.rs pub struct Config {     pub query: String,     pub filename: String, }  impl Config {     pub fn new(mut args: std::env::Args) -> Result {         if args.len() < 3 {             return Err("not enough arguments");         }         args.next(); //由于第一个参数没有用,所以直接执行next消费掉                      // let query = args[1].clone();         let query = match args.next() {             Some(arg) => arg,             None => return Err("Did not get a query string!"),         };         // let filename = args[2].clone();         let filename = match args.next() {             Some(arg) => arg,             None => return Err("Did not get a file name!"),         };         Ok(Config { query, filename })     } }  pub fn search<"a>(query: &str, contents: &"a str) -> Vec<&"a str> {     // let mut results = Vec::new();     // for line in contents.lines() {     //     if line.contains(query) {     //         results.push(line);     //     }     // }     // results     //减少临时变量     contents         .lines()         .filter(|line| line.contains(query))         .collect() }
  这里search改完了,search_case_insensitive也按照这个例子改。 性能比较
  前面把for循环的search改成了使用迭代器实现,通过性能测试,发现迭代器版本性能更好。这是因为迭代器,作为一个高级的抽象,被编译成了与手写的底层代码性能差不多的代码。 零开销抽象(Zero-Cost Abstraction)
  前面所说的高级的抽象就叫做零开销抽象或零成本抽象,使用它时不会引入额外的运行时开销。
  作为另一个例子,这里有一些取自于音频解码器的代码。解码算法使用线性预测数学运算(linear prediction mathematical operation)来根据之前样本的线性函数预测将来的值。这些代码使用迭代器链来对作用域中的三个变量进行了某种数学计算:一个叫 buffer 的数据 slice、一个有 12 个元素的数组 coefficients、和一个代表位移位数的 qlp_shift。例子中声明了这些变量但并没有提供任何值;虽然这些代码在其上下文之外没有什么意义,不过仍是一个简明的现实中的例子,来展示 Rust 如何将高级概念转换为底层代码:let buffer: &mut [i32]; let coefficients: [i64; 12]; let qlp_shift: i16;  for i in 12..buffer.len() {     let prediction = coefficients.iter()                                  .zip(&buffer[i - 12..i])                                  .map(|(&c, &s)| c * s as i64)                                  .sum::() >> qlp_shift;     let delta = buffer[i];     buffer[i] = prediction as i32 + delta; } ```language
  为了计算 prediction 的值,这些代码遍历了 coefficients 中的 12 个值,使用 zip 方法将系数与 buffer 的前 12 个值组合在一起。接着将每一对值相乘,再将所有结果相加,然后将总和右移 qlp_shift 位。
  像音频解码器这样的程序通常最看重计算的性能。这里,我们创建了一个迭代器,使用了两个适配器,接着消费了其值。Rust 代码将会被编译为什么样的汇编代码呢?好吧,在编写本书的这个时候,它被编译成与手写的相同的汇编代码。遍历 coefficients 的值完全用不到循环:Rust 知道这里会迭代 12 次,所以它"展开"(unroll)了循环。展开是一种移除循环控制代码的开销并替换为每个迭代中的重复代码的优化。
  所有的系数都被储存在了寄存器中,这意味着访问他们非常快。这里也没有运行时数组访问边界检查。所有这些 Rust 能够提供的优化使得结果代码极为高效。现在知道这些了,请放心大胆的使用迭代器和闭包吧!他们使得代码看起来更高级,但并不为此引入运行时性能损失。

滋润双眼,放松眼周肌肉,你需要这款护眼仪每天上班盯着电脑工作,然后就是手机刷刷刷回家后又是各种游戏,不管是游戏还是各种app的社交,突然发现除了睡觉时间,眼睛要看各种屏幕,加上常常熬夜的你,眼睛经常会干涩流眼泪,加上熬夜还在为孩子刷牙头疼,看看这款牙刷吧8现在市面上有很多款造型可爱的儿童电动u型牙刷,其凭借着独特的造型吸引了很多人。但也有不少朋友还对u型牙刷仍心存疑惑,总在怀疑U型牙刷是否能像传统牙刷一般刷得干净,是否更适合儿童使小米MIX4终于来了FHD真全面屏,120W70W快充如果说下半年大家最期待的新机是啥,除了iPhone13系列和华为P50系列之外,应该就是停更很久的小米MIX4了。目前可以确定的是,今年肯定会有MIX4。昨天数码闲聊站爆料你们期待风柔音轻,凉爽跟随,飞利浦ACR3144TF无叶塔扇体验对于塔扇这一品类,我一开始是拒绝的,因为去年的时候买过一个塔扇放在办公室用,,但是它运作的时候的时候底座非常不稳,而且出风口的风量很小,尽管可以开启摇头模式,但是出风口的面积只有那我在北方买了一个除湿机!德业除湿机使用体验江南35月的天气,一般都是在潮湿中度过的。这段时间,由于工作的调动,要去北方工作半年,本以为躲过了南方的黄梅天,结果这几天北方的连续的雨水,做梦也没想到北方今年几乎是三天一场大雨两全系自动挡200马力,颜值耐看空间大,入手第五代途胜L很划算?如果20万以内的预算想要落地一台合资的紧凑型SUV,这个价位能买到什么车?说到紧凑型SUV以及20万预算这两个关键词,大家会更容易想到日系三侠,但是如果要选择日系三侠的话,配置方面年轻时尚大胆的DELL灵越5000fit简单体验某日,基友让我给他妹妹选购一台笔记本,在校大学生,不玩游戏没有专业软件需求,预算5000,我挑了几款可他妹妹就选中了这台Dell灵越5000fit,其实我挺不看好这款的,奈何帮别人花小钱办大事,川宇C396读卡器简单体验台式机没有读卡器,相机拍了照片以后转到电脑上特别麻烦,所以就打算入个读卡器,只有两个要求一是够便宜,这个东西用的频率不会特别高,很容易哪天就找不到了,太贵了感觉不划算二是USB3。颜值高又不失实力的千元烤箱选什么作为一名精致美食追求者,一直想进自己烘焙烹饪的巨坑,奈何总是没找到一款适合我这种小白想要真正好上手又不失格调的家电。在经过多种厨房电器的尝试后,现在,如果你问我什么小家电最容易简单功能升级协议更换小米人体传感器2有没有get到你的点?12月2日上午10点,小米人体传感器2正式登陆小米商城小米之家的众筹平台开启众筹,众筹价格49元还包邮,这个价格真的是相当有亲和力的,非常感谢张大妈众测平台,让我能够提前体验到这个2030年,家庭WiFi路由器和扩展器市场将达180亿美元市场简介市场调研机构TMRResearchInsights发布了一份有关全球家庭WiFi路由器和扩展器市场的重要见解。就市场收入而言,预计到2030年,家庭WiFi路由器和扩展器市
最好用的电脑软件,私人珍藏7款良心电脑软件现在小巧绿色无广告的电脑软件,成为了我们对电脑软件的最基本要求,今天小王就给大家分享,个人觉得电脑中最好用的7款基本软件,让你远离垃圾软件和广告弹窗。我们首先来说说优秀免费的解压缩华为ICT大赛纳入2020全国普通高校大学生竞赛项目名单2021年3月22日,中国高等教育学会高校竞赛评估与管理体系研究工作组发布2020全国普通高校大学生竞赛排行榜。华为ICT大赛首次纳入2020全国普通高校大学生竞赛排行榜内竞赛项目第四届计算机教育20人论坛举办探讨计算机创新人才培养2021年5月2223日,由教育部高等学校计算机类专业教学指导委员会教育部高等学校软件工程专业教学指导委员会教育部高等学校大学计算机课程教学指导委员会主办,高等教育出版社华为承办的全球大牌齐聚重庆摩博会京东汽车加速摩托车领域布局9月17日至20日,中国摩托车行业的年度盛会第十九届中国国际摩托车博览会(以下简称中国摩博会)在重庆国际博览中心盛大举行。本届中国摩博会采取一会多地线上与线下相结合的方式举办,汇聚贤达下午茶工作再忙,烦恼再多,美食总能击中内心为什么小工厂4000元月的工资招不到年轻人,而星巴克3000元每月却大受年轻求职者的追捧?其实不难理解星巴克优雅的工作环境,完善的福利待遇,良好的晋升空间,分分钟秒杀小工厂的脏乱差年度最佳SUV和跨界车之2021款吉普牧马人2021吉普牧马人吉普车优点标志性设计,出色的越野能力,可移动的门和车顶。缺点舒适的乘客空间,巡航时嘈杂的机舱,比其他类似汽车的竞争对手更粗糙。结论标志性的吉普牧马人利用现代技术来年度最佳休旅车之2020款沃尔沃V902020款沃尔沃V90优点内外突显斯堪的纳维亚设计,丰富的技术和安全功能,比同等大小的SUV更好的操控性。缺点仅适用于适度的四缸发动机,平稳的行驶,迟滞的信息娱乐屏幕响应时间。结论年度最佳轿跑车之2020款奥迪A52020款奥迪A5优点自信的转弯,涡轮增压提供强大动力,令人惊讶的大后备箱。缺点许多驾驶员辅助功能不是标准功能,没有手动变速箱。结论A5具有宽敞的座舱,技术含量高的功能表和漂亮的造年度最佳SUV和跨界车之2020款宝马X72021款宝马X7优点动力总成具有美味而平稳的动力,内部像图书馆一样安静,但更加舒适,AlpinaXB7异常敏捷且运动。缺点拐弯时车身侧倾过多,机舱和货物空间比预期的要小,电动后排年度最佳SUV和跨界车之2021款起亚Telluride2021款起亚Telluride优点豪华小屋,绝对便宜的价格,非常适合牵引家庭。缺点并不是特别省油,无感情的驾驶行为,自适应巡航控制却很繁琐。结论对于需要牵引家庭并保持正直的人来说小爱同学uwp电脑版正式上线,小爱同学下载安装教程在这里哦近日,听说小爱同学UWP上架Win10应用商店,但是我搜不到,我就去网上找了一下,真被找到了,也安装了成功,目测应该所有的品牌的电脑都可以安装,小米打造的智能协同办公系统,不仅可以