Rust 学习笔记:使用迭代器改进 minigrep
Rust 学习笔记:使用迭代器改进 minigrep
- Rust 学习笔记:使用迭代器改进 minigrep
- 不使用 clone,而使用迭代器
- 使用迭代器适配器使代码更清晰
- 在循环或迭代器之间进行选择
Rust 学习笔记:使用迭代器改进 minigrep
前情提要:https://blog.csdn.net/ProgramNovice/article/details/148192426
有了这些关于迭代器的新知识,我们可以通过使用迭代器使代码更清晰、更简洁。让我们看看迭代器如何改进 Config::build 函数和 search 函数的实现。
不使用 clone,而使用迭代器
原函数:
impl Config {pub fn build(args: &[String]) -> Result<Config, &'static str> {if args.len() < 3 {return Err("not enough arguments");}let query = args[1].clone();let file_path = args[2].clone();let ignore_case = env::var("IGNORE_CASE").is_ok();Ok(Config { query, file_path, ignore_case })}
}
有了关于迭代器的新知识,我们可以修改构建函数,使其接受迭代器的所有权作为参数,将 String 值从迭代器移到 Config 中,而不是调用 clone 并进行新的分配。
env::args 函数返回一个迭代器,类型是 std::env::Args,该类型实现了 Iterator trait 并返回 String 值。
修改代码,使得其所有权直接传递给 Config::build 函数。
fn main() {let config = Config::build(env::args()).unwrap_or_else(|err| {eprintln!("Problem parsing arguments: {err}");process::exit(1);});// --skip--
}
接下来,我们需要更新 Config::build 函数:
impl Config {pub fn build(mut args: impl Iterator<Item = String>) -> Result<Config, &'static str> {args.next();let 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"),};let ignore_case = env::var("IGNORE_CASE").is_ok();Ok(Config { query, file_path, ignore_case })}
}
我们更新了 Config::build 函数的签名,所以参数 args 有一个泛型类型,trait 约束为 impl Iterator<Item = String> 而不是 &[String],这意味着 args 可以是任何实现 Iterator trait 并返回 String 项的类型。因为我们获得了 args 的所有权我们将通过迭代来改变 args,我们可以在 args 参数的说明中添加 mut 关键字来使它可变。
使用迭代器适配器使代码更清晰
项目的 search 函数中利用了迭代器:
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
}
我们可以使用迭代器适配器方法以更简洁的方式编写此代码。这样做还可以避免使用可变的中间结果向量。
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> {contents.lines().filter(|line| line.to_lowercase().contains(&query.to_lowercase())).collect()
}
在循环或迭代器之间进行选择
大多数 Rust 程序员更喜欢使用迭代器风格。一开始很难掌握窍门,但是一旦了解了各种迭代器适配器及其功能,就会更容易理解迭代器。
代码没有处理循环的各个部分和构建新的向量,而是专注于循环的高级目标。这抽象掉了一些常见的代码,因此更容易看到这些代码特有的概念,例如迭代器中的每个元素必须通过的过滤条件。
相关文章:
Rust 学习笔记:使用迭代器改进 minigrep
Rust 学习笔记:使用迭代器改进 minigrep Rust 学习笔记:使用迭代器改进 minigrep不使用 clone,而使用迭代器使用迭代器适配器使代码更清晰在循环或迭代器之间进行选择 Rust 学习笔记:使用迭代器改进 minigrep 前情提要࿱…...

多线程(5)——单例模式,阻塞队列
目录 单例模式饿汉模式懒汉模式—单线程版懒汉模式—多线程版(经典面试题)懒汉模式—多线程版(改进) 阻塞队列阻塞队列是什么生产者消费者模型标准库中的阻塞队列-BlockingQueue阻塞队列实现 单例模式 单例模式是一种设计模式&am…...
React整合【ECharts】教程004:饼图的构建和基本设置
文章目录 6、饼图6.1 开启圆角环形6.2 设置扇区间隙6.3 开启深色模式6.4 开启南丁格尔玫瑰图6.5 修改数据重绘饼图6.6 完整代码下载6、饼图 6.1 开启圆角环形 1️⃣添加圆角环形开关: <div style={{marginTop:10px}}>圆角环形:<Switch checkedChildren="开启…...

视频监控汇聚平台EasyCVR工业与安全监控:防爆摄像机的安全应用与注意事项
石油、化工、煤矿等行业存在易燃易爆气体、粉尘,普通监控设备易因电火花、高温引发爆炸火灾。随着工业规模扩大,安全生产监控需求激增,防爆摄像机成为保障安全的关键。加之国家法规与行业标准对危险环境监控设备要求严格,规范其应…...
Android 倒计时总结
文章目录 Android 倒计时总结Handler方案CountDownTimer方案Timer方案Flow方案总结源码下载 Android 倒计时总结 Handler方案 class MyHandler(private val intervalTime: Long, // 间隔private val totalTime: Long, // 总时长onTick: (Long) -> Unit, // 每秒回调onFini…...

基于 Redis 实现分布式锁:原理及注意事项
文章目录 基于 Redis 实现分布式锁:原理及注意事项基于 Redis 实现分布式锁的原理Redis 分布式锁的过期时间和锁续期机制如何防止锁被其他 goroutine 删除?Redis 分布式锁存在的单点故障问题:基于 RedLock 的解决方案高并发场景中 Redis 分布…...

手机设备多?怎样设置IP保证不关联
在移动互联网时代,多设备运营(如电商、游戏工作室、社交媒体矩阵)常面临IP关联风险,轻则账号受限,重则封禁。以下提供6种高效设置独立IP的方法,结合技术原理与实操建议,助您打造稳定合规的运营环…...
Linux 中常见的安全与权限机制
Linux 中常见的安全与权限机制主要包括以下几类,从文件系统权限到系统级访问控制,构建了多层次的安全保障体系。 🔐 一、文件权限与用户管理 1. 基本权限(rwx) r(read):读取文件内…...
Golang|单例模式
单例模式定义:在程序运行期间,某个结构体只创建一个实例。适用场景:如数据库连接池,在整个程序运行期间只需要一个连接池实例。 方案一:通过加锁的方式,如读写锁,确保在并发情况下只创建一个实…...

哈尔滨工业大学计算机系统大作业程序人生-Hello’s P2P
摘 要 文章以C语言程序设计经典案例hello.c为研究对象,系统解析程序在计算机系统中的完整生命周期。剖析源代码通过预处理、编译、汇编、链接四阶段演化为可执行目标程序的编译系统工作机制,继而从进程视角揭示程序运行时计算机体系结构的协同运作&…...
小程序定制开发:从需求到落地,打造企业专属数字化入口
在移动互联网时代,小程序已成为企业连接用户的核心载体。定制开发因能深度匹配企业需求,正成为各行业数字化转型的优选方案。以下从优势、流程、技术、案例四方面展开,助你快速掌握关键要点。 一、定制开发的核心优势 1. 高度个性化&#x…...
【C/C++】基于 Docker 容器运行的 Kafka + C++ 练手项目
文章目录 基于 Docker 容器运行的 Kafka C 练手项目1 项目目的2 项目框架3 代码4 编译运行5 功能与接口说明5.1 Producer 接口:producer.cpp关键调用流程参数说明 5.2 Consumer 接口:consumer.cpp关键调用流程消费流程中注意 5.3 工程技术点 基于 Docke…...

Linux系统管理与编程24:基础条件准备-混搭“本地+阿里云”yum源
兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 1.添加宿主机共享文件夹 Linux虚拟机可以和宿主机共享文件夹,这样有利于工具文件的共享。具体操作如下: 1)vmware workstation共享文件夹 虚拟机…...
新一代Python管理UV完全使用指南|附实际体验与效果对比
简介 uv是新一代的Python项目管理工具,具备开发一个完整项目的所有功能点: 功能点描述包管理完全替代pip的功能,支持包的安装、升级、卸载等操作虚拟环境管理内置虚拟环境创建和管理,无需额外安装virtualenv或venv依赖解析与锁定…...

如何在 Windows 10 PC 上获取 iPhone短信
您可以轻松地将媒体数据从 iPhone 传输到 Windows 计算机,并直接访问计算机上的数据。但是,您可以在 Windows 10 PC 上接收 iPhone 短信吗?有什么功能或工具支持它吗?如果您发现在 Windows 10 PC 上接收 iPhone 消息很困难&#x…...
STM32程序运行不了,仿真功能也异常,连断点和复位都异常了
先检查有没有出现复位引脚rst短接0的情况 在检查是否出现明明没配置该外设你却偏偏要使用的情况,比如串口没配置你却偏要发送,引脚没配置你却偏要读取 这几个可能最好的办法就是从开头一行一行注释再运行看看能不能跑起来 还可以用以下方法 检查硬…...

Linux 系统中的软链接与硬链接
目录 一、什么是软链接? 1. 创建软链接 2. 软链接的特性 3. 软链接的用途 二、什么是硬链接? 1. 创建硬链接 2. 硬链接的特性 3. 硬链接的用途 4. 目录硬链接的特殊性 编辑 三、软链接与硬链接的区别 1. inode 编号 2. 路径依赖 3. 删除行…...

Python爬虫第22节- 结合Selenium识别滑动验证码实战
目录 一、引言 二、滑动验证码原理与反爬机制 2.1 验证码原理 2.2 反爬机制 三、工程实战:滑动验证码识别全流程 3.1 工程准备 3.1.1 环境依赖 3.1.2 目标网站与验证码识别案例 3.2 核心破解流程 3.2.1 自动化打开网页与登录 3.2.2 获取验证码图片&#…...
【C/C++】chrono简单使用场景
chrono使用场景举例 1 输出格式化字符串 示例代码 auto now std::chrono::system_clock::now(); auto t std::chrono::system_clock::to_time_t(now); auto ms std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;std::ostrin…...

Escrcpy(安卓手机投屏软件) v1.29.6 中文绿色版
在数字设备日益普及的今天,用户对于设备的控制和管理需求也在不断增加。对于Android设备用户来说,Escrcpy这款强大的工具无疑是一个福音。它不仅提供了直观的图形化界面,让用户能够轻松显示和控制自己的Android设备,还以完全免费开…...
Oracle MOVE ONLINE 实现原理
Oracle MOVE ONLINE 实现原理 Oracle 的 MOVE ONLINE 操作是一种在线重组表的技术,允许在不中断业务的情况下重新组织表数据。以下是其实现原理的详细分析: 基本概念 MOVE ONLINE 是 Oracle 12c 引入的特性,用于替代传统的 ALTER TABLE ..…...

Linux:深入理解网络层
网络层在复杂的网络环境中确定一个合适的路径.传输到指定的网络中 一、网络层的理解 问题1:为什么要有网络层的概念呢?? ——>我们先来讲一个故事: 假设我在学校里被誉为数学大神,是因为我的数学有考满分的能力&…...
【设计模式】简单工厂模式,工厂模式,抽象工厂模式,单例,代理,go案例区分总结
工厂模式三种类型: 一、简单工厂模式(Simple Factory) 定义: 用一个工厂类,根据传入的参数决定创建哪一种具体产品类实例。 面试说法: 由一个统一的工厂创建所有对象,增加新产品时需要修改工…...

Linux_编辑器Vim基本使用
✨✨ 欢迎大家来到小伞的大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:LInux_st 小伞的主页:xiaosan_blog 制作不易!点个赞吧!!谢谢喵!&a…...

vue展示修改前后对比,并显示修改标注diff
动态父组件 <template><el-buttontype"primary"size"small"plainclick"showDiffDialog(subItem)">查看修改内容</el-button><TextDiffDialogv-model:visible"diffDialogVisible":before"currentDiffItem?.…...

LiveWallpaperMacOS:让你的 Mac 桌面动起来
随着桌面美化需求的不断提升,用户对于桌面壁纸的要求已经不再局限于静态图片。越来越多的 Mac 用户希望桌面能像 Windows 一样,拥有动态壁纸,展现个性、提升体验。LiveWallpaperMacOS 正是这样一款让你的 Mac 桌面焕发活力的开源项目。 本文将详细介绍 LiveWallpaperMacOS …...
[预训练]Encoder-only架构的预训练任务核心机制
原创文章1FFN前馈网络与激活函数技术解析:Transformer模型中的关键模块2Transformer掩码技术全解析:分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer核心技术解析LCPO方法:精准控制推理长度的新突破5Transformer模…...

07-后端Web实战(部门管理)
5. 修改部门 对于任何业务的修改功能来说,一般都会分为两步进行:查询回显、修改数据。 5.1 查询回显 5.1.1 需求 当我们点击 "编辑" 的时候,需要根据ID查询部门数据,然后用于页面回显展示。 5.1.2 接口描述 参照参照…...

mysql ACID 原理
序言:ACID 是一组数据库设计原则,他是业务数据和关键业务程序的可靠性保障。 1、atomicity(原子性) 依赖如下能力 autocommit commit rollback2、一致性 2.1 double write buffer 1、定义:double write buffer 是…...

[Rust_1] 环境配置 | vs golang | 程序运行 | 包管理
目录 Rust 环境安装 GoLang和Rust 关于Go 关于Rust Rust vs. Go,优缺点 GoLang的优点 GoLang的缺点 Rust的优点 Rust的缺点 数据告诉我们什么? Rust和Go的主要区别 (1) 性能 (2) 并发性 (3) 内存安全性 (4) 开发速度 (5) 开发者体验 Ru…...