当前位置: 首页 > news >正文

Rust学习之实现命令行小工具minigrep(二)

Rust学习之实现命令行小工具minigrep(二)

Rust学习之实现命令行小工具minigrep(一)

前言

继续记录一下Rust 语言学习过程,上次写了一个命令行查找字符串的小项目minigrep。学习完了闭包(Closures)和迭代器(Iterators)之后,我们使用这两个技术来改进minigrep这个项目。

本文源码:代码仓库

改进实现

minigrep1 这个项目中,lib.rs文件,我们对Config的build方法中进行改进。

上次我们的代码如下:


pub struct Config {pub query: String,pub file_path: String,pub ignore_case: bool,
}impl Config {pub fn build(args: &[String]) -> Result<Config, &'static str> { // 1if args.len() < 3 {return Err("Not enouth arguments"); // 传入参数不够}let query = args[1].clone();let file_path = args[2].clone();let ignore_case = env::var("IGNORE_CASE=1").is_ok();Ok(Config {query,file_path,ignore_case})}
}

代码里args: &[String] 表示传进来的是字符串的切片引用,而后面的Config 需要拥有queryfile_path 以及ignore_case。所以在代码中不得不克隆一份。

改进build方法

现在可以使用迭代器(Iterators)代替&[String],对这里build方法进行改进,改进步骤如下:

  1. 直接将env::args() 传入 Config::build 方法,env::args() 返回一个Iterator
  2. build 方法声明中,args 参数类型改为impl Iterator<Item = String>
  3. 使用迭代器的next方法获取元素并使用match语法进行匹配

main.rs


use std::env;
use std::process;use minigrep1::Config;fn main() {let args: Vec<String> = env::args().collect();// dbg!(args); // stderr// 传入两个参数// &args 改为 env::args()let config = Config::build(env::args()).unwrap_or_else(|err| {eprintln!("Problem parsing arguments: {}", err);process::exit(1);});if let Err(e) = minigrep1::run(config) {eprintln!("Application error {}", e);process::exit(1)}
}

lib.rs

改进前:


pub fn build(args: &Vec<String>) -> Result<Config, &'static str> {if args.len() < 3 {return Err("Not enouth arguments"); // 传入参数不够}let query = args[1].clone();let file_path = args[2].clone();
}

改进后:

impl Config {pub fn build(mut args: impl Iterator<Item = String>) -> Result<Config, &'static str> {args.next(); // skip the first argumentlet query = match args.next() {Some(arg) => arg,None => return Err("Didn't get a query string"),};let file_path = match args.next() {Some(arg) => arg,None => return Err("Didn't get a file_path string"),};let ignore_case = env::var("IGNORE_CASE=1").is_ok();Ok(Config {query,file_path,ignore_case})}
}

改进search方法

search方法中,是对文本进行遍历,进行判断查找。这里可以用迭代器,还可以用闭包。contents.lines() 返回一个迭代器

用迭代器把之前的for 循环都替换掉,使用filter时使用闭包

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {contents.lines().filter(|line| line.contains(query)).collect()
}

同理,search_case_insensitive方法也同样使用迭代器和闭包进行修改

改进前:

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {let mut result = Vec::new();let query = query.to_lowercase();for line in contents.lines() {if line.to_lowercase().contains(&query) {result.push(line);}}result
}

改进后:

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {let query: String = query.to_lowercase();contents.lines().filter(|line| line.to_lowercase().contains(&query)).collect()
}

总结

项目使用迭代器和闭包优化之后首先代码效率提高了,为了将引用切片转移到Config中需要使用消耗性能的clone方法,现在我们就不需要了。迭代器迭代适配器filter 方法的使用让我们编写更加简明的代码。

相关文章:

  • qt/C++面试题自用学习(更新中)
  • Gitlab SSH Jenkins Pipeline Supervisor部署
  • 大模型训练显存压缩实战:ZeRO-3 vs 梯度累积 vs 量化混合策略
  • 深度为16,位宽8bit的单端口SRAM——学习记录
  • 全网通emotn ui桌面免费吗?如何开机自启动
  • leetcode:3210. 找出加密后的字符串(python3解法)
  • 淘宝商品数据高并发采集方案:API 接口限流机制与分布式调用实战
  • SnailJob:分布式环境设计的任务调度与重试平台!
  • Centos/RedHat 7.x服务器挂载ISCSI存储示例(无多路径非LVM)
  • opencv腐蚀的操作过程
  • DeepSeek高阶玩法教程:从入门到精通的实战案例
  • 晶晨线刷工具下载及易错点说明:Key文件配置错误/mac剩余数为0解决方法
  • 鸿蒙系统开发状态更新字段区别对比
  • SAP S4HANA embedded analytics
  • 【QT】 QT定时器的使用
  • RPCRT4!OsfCreateRpcAddress函数分析之AssociationBucketMutexMemory数组的填充
  • Grass.io项目现状:DePIN亮眼明星,扩张中的AI数据银行
  • C#核心学习(三)常见的泛型数据结构类(1)List和Dictionary
  • DDoS(分布式拒绝服务)攻击
  • RNN - 循环神经网络(概念介绍)
  • 两部门调度部署“五一”假期安全防范工作,要求抓好旅游安全
  • 国台办:“台独”是绝路,外人靠不住
  • TCL科技一季度净利增超三倍,去年半导体显示业务营收创新高
  • “中国游”带火“中国购”,“即买即退”让外国游客购物更丝滑
  • 美联合健康集团高管枪杀案嫌疑人对谋杀指控不认罪
  • 中央政治局会议举行,传递三重确定性