【Rust】——使用迭代器处理元素序列

💻博主现有专栏:

                C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等
🥏主页链接:

                Y小夜-CSDN博客

目录

🎯Iterator trait和next方法

🎯消费迭代器的方法

🎯产生其他迭代器的方法

🎯使用捕获其环境的闭包


        迭代器模式允许你对一个序列的项进行某些处理。迭代器iterator)负责遍历序列中的每一项和决定序列何时结束的逻辑。当使用迭代器时,我们无需重新实现这些逻辑。

在 Rust 中,迭代器是 惰性的lazy),这意味着在调用方法使用迭代器之前它都不会有效果。

    let v1 = vec![1, 2, 3];let v1_iter = v1.iter();

        迭代器被储存在 v1_iter 变量中。一旦创建迭代器之后,可以选择用多种方式利用它。在第三章的示例 3-5 中,我们使用 for 循环来遍历一个数组并在每一个项上执行了一些代码。在底层它隐式地创建并接着消费了一个迭代器,不过直到现在我们都一笔带过了它具体是如何工作的。

        例子将迭代器的创建和 for 循环中的使用分开。迭代器被储存在 v1_iter 变量中,而这时没有进行迭代。一旦 for 循环开始使用 v1_iter,接着迭代器中的每一个元素被用于循环的一次迭代,这会打印出其每一个值:

    let v1 = vec![1, 2, 3];let v1_iter = v1.iter();for val in v1_iter {println!("Got: {}", val);}

        在标准库中没有提供迭代器的语言中,我们可能会使用一个从 0 开始的索引变量,使用这个变量索引 vector 中的值,并循环增加其值直到达到 vector 的元素数量。

🎯Iterator trait和next方法

        迭代器都实现了一个叫做 Iterator 的定义于标准库的 trait。这个 trait 的定义看起来像这样:

pub trait Iterator {type Item;fn next(&mut self) -> Option<Self::Item>;// 此处省略了方法的默认实现
}

        注意这里有一个我们还未讲到的新语法:type Item 和 Self::Item,它们定义了 trait 的 关联类型associated type)。

  next 是 Iterator 实现者被要求定义的唯一方法。next 一次返回迭代器中的一个项,封装在 Some 中,当迭代器结束时,它返回 None

    #[test]fn iterator_demonstration() {let v1 = vec![1, 2, 3];let mut v1_iter = v1.iter();assert_eq!(v1_iter.next(), Some(&1));assert_eq!(v1_iter.next(), Some(&2));assert_eq!(v1_iter.next(), Some(&3));assert_eq!(v1_iter.next(), None);}

        注意 v1_iter 需要是可变的:在迭代器上调用 next 方法改变了迭代器中用来记录序列位置的状态。换句话说,代码 消费(consume)了,或使用了迭代器。每一个 next 调用都会从迭代器中消费一个项。使用 for 循环时无需使 v1_iter 可变因为 for 循环会获取 v1_iter 的所有权并在后台使 v1_iter 可变。

🎯消费迭代器的方法

   Iterator trait 有一系列不同的由标准库提供默认实现的方法;你可以在 Iterator trait 的标准库 API 文档中找到所有这些方法。一些方法在其定义中调用了 next 方法,这也就是为什么在实现 Iterator trait 时要求实现 next 方法的原因。

        这些调用 next 方法的方法被称为 消费适配器consuming adaptors),因为调用它们会消耗迭代器。一个消费适配器的例子是 sum 方法。

    #[test]fn iterator_sum() {let v1 = vec![1, 2, 3];let v1_iter = v1.iter();let total: i32 = v1_iter.sum();assert_eq!(total, 6);}

调用 sum 之后不再允许使用 v1_iter 因为调用 sum 时它会获取迭代器的所有权。

🎯产生其他迭代器的方法

    Iterator trait 中定义了另一类方法,被称为 迭代器适配器iterator adaptors),它们允许我们将当前迭代器变为不同类型的迭代器。可以链式调用多个迭代器适配器。不过因为所有的迭代器都是惰性的,必须调用一个消费适配器方法以便获取迭代器适配器调用的结果。

    let v1: Vec<i32> = vec![1, 2, 3];v1.iter().map(|x| x + 1);

不过这些代码会产生一个警告

$ cargo runCompiling iterators v0.1.0 (file:///projects/iterators)
warning: unused `Map` that must be used--> src/main.rs:4:5|
4 |     v1.iter().map(|x| x + 1);|     ^^^^^^^^^^^^^^^^^^^^^^^^^|= note: `#[warn(unused_must_use)]` on by default= note: iterators are lazy and do nothing unless consumedwarning: `iterators` (bin "iterators") generated 1 warningFinished dev [unoptimized + debuginfo] target(s) in 0.47sRunning `target/debug/iterators`

        为了修复这个警告并消费迭代器获取有用的结果,我们将使用第十二章示结合 env::args 使用的 collect 方法。这个方法消费迭代器并将结果收集到一个数据结构中。

    let v1: Vec<i32> = vec![1, 2, 3];let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();assert_eq!(v2, vec![2, 3, 4]);

        因为 map 获取一个闭包,可以指定任何希望在遍历的每个元素上执行的操作。这是一个展示如何使用闭包来自定义行为同时又复用 Iterator trait 提供的迭代行为的绝佳例子。  

        可以链式调用多个迭代器适配器来以一种可读的方式进行复杂的操作。不过因为所有的迭代器都是惰性的,你需要调用一个消费适配器方法从迭代器适配器调用中获取结果。

🎯使用捕获其环境的闭包

        很多迭代器适配器接受闭包作为参数,而通常指定为迭代器适配器参数的闭包会是捕获其环境的闭包。

#[derive(PartialEq, Debug)]
struct Shoe {size: u32,style: String,
}fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {shoes.into_iter().filter(|s| s.size == shoe_size).collect()
}#[cfg(test)]
mod tests {use super::*;#[test]fn filters_by_size() {let shoes = vec![Shoe {size: 10,style: String::from("sneaker"),},Shoe {size: 13,style: String::from("sandal"),},Shoe {size: 10,style: String::from("boot"),},];let in_my_size = shoes_in_size(shoes, 10);assert_eq!(in_my_size,vec![Shoe {size: 10,style: String::from("sneaker")},Shoe {size: 10,style: String::from("boot")},]);}
}

  shoes_in_my_size 函数获取一个鞋子 vector 的所有权和一个鞋子大小作为参数。它返回一个只包含指定大小鞋子的 vector。

  shoes_in_my_size 函数体中调用了 into_iter 来创建一个获取 vector 所有权的迭代器。接着调用 filter 将这个迭代器适配成一个只含有那些闭包返回 true 的元素的新迭代器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/789662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes控制器(四)______StatefulSet

控制器介绍 StatefulSet&#xff1a; 是Kubernetes中用于管理有状态应用的控制器。与Deployment不同&#xff0c;StatefulSet用于部署和管理需要持久标识、有序部署和唯一网络标识的 Pod。典型的用例包括数据库、缓存和队列等有状态应用。&#xff08;有状态服务&#xff1a;单…

分享几个好用的电商API接口(可测试)

以下是一些好用的电商API接口&#xff0c;这些接口都可以用于获取电商平台的商品、订单、物流等相关信息&#xff0c;并提供了测试功能以确保接口的稳定性和可用性&#xff1a; 请求示例&#xff0c;API接口接入Anzexi58 淘宝开放平台API&#xff1a;淘宝开放平台提供了丰富的…

Keil 警告解决 : warning: #870-D: invalid multibyte character sequence

说明&#xff1a;在Keil项目编译时出现了几个 warning: #870-D: 的警告&#xff0c;接下来分析解决这个警告。 注意&#xff1a;在尝试解决问题前一定要将整个工程打包成压缩文件备份&#xff0c;以防更改失败变文件成乱码。 1.警告内容 warning: #870-D: warning: #870-…

2024.2.27力扣每日一题——统计树中的合法路径数目

2024.2.27 题目来源我的题解方法一 埃氏筛深度优先遍历 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2867 我的题解 方法一 埃氏筛深度优先遍历 分别以质数节点为根&#xff0c;用「深度优先搜索」的方式&#xff0c;递归搜索所有的非质数的子树&#xff0c;并求出所…

Android Monkey自动化测试

monkey一般用于压力测试&#xff0c;用户模拟用户事件 monkey 基本用法 adb shell monkey [参数] [随机事件数]monkey常用命令 -v&#xff1a;用于指定反馈信息级别&#xff0c;总共分三个等级-v -v -vadb shell mokey -v -v -v 100-s&#xff1a;用于指定伪随机数生成器的种…

CentOS7安装flink1.17完全分布式

前提条件 准备三台CenOS7机器&#xff0c;主机名称&#xff0c;例如&#xff1a;node2&#xff0c;node3&#xff0c;node4 三台机器安装好jdk8&#xff0c;通常情况下&#xff0c;flink需要结合hadoop处理大数据问题&#xff0c;建议先安装hadoop&#xff0c;可参考 hadoop安…

impnt只读,燕用,必填,提示词(占位符)属性分别是什么

readonly 属性规定输入字段为只读&#xff08;不能修改&#xff09; <input type"text" placeholder"点我啊" readonly/> disabled 属性规定输入字段是禁用的 <input type"text" placeholder"点我啊" disabled/> re…

XXLJob中GLUE模式实现在线编写java/shell/python/php/nodejs/powerShell---SpringCloud工作笔记202

1.起因: 之前就一直想实现类似的功能,今天总于找到有可以参考的东西了,这个思路可以帮助实现这种功能. 2.获得灵感 就是:我想实现通过在线编写代码,来扩展我们平台的能力,这样随着业务的扩展,不用我们每次都修改了代码,再去部署,这样就比较麻烦,今天偶尔发现,对于xxljob来说.有…

OSCP靶场--ProStore

OSCP靶场–ProStore 考点(node.js代码注入gdb-list源文件c语言命令执行) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.200.250 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-01 09:18 EDT Nmap scan report…

Stream2Graph论文翻译

Stream2Graph: Dynamic Knowledge Graph for Online Learning Applied in Large-scale Network Abstract 知识图谱(KG)是用于存储某个领域(医疗保健、金融、电子商务、ITOps等)中的知识的有价值的信息来源。大多数工业KG本质上是动态的&#xff0c;因为它们定期更新流数据(客…

Scala第十八章节(Iterable集合、Seq集合、Set集合、Map集合以及统计字符个数案例)

Scala第十八章节 章节目标 掌握Iterable集合相关内容.掌握Seq集合相关内容.掌握Set集合相关内容.掌握Map集合相关内容.掌握统计字符个数案例. 1. Iterable 1.1 概述 Iterable代表一个可以迭代的集合, 它继承了Traversable特质, 同时也是其他集合的父特质. 最重要的是, 它定…

git tag 恢复代码

在Git中&#xff0c;标签&#xff08;tag&#xff09;用于标记特定的提交&#xff0c;它们并不直接涉及恢复代码的过程。恢复代码通常意味着回退到某个历史提交或找回之前删除的文件。虽然标签可以帮助你定位到特定的提交&#xff0c;但恢复代码本身需要使用其他Git命令。 如果…

python文件的写入操作

文件的写入和追加 import time #1.打开文件 fopen("F:/python/helloworld/1.txt","w",encoding"UTF-8")#2.文件写入 f.write("hello world") #3.内容刷新 f.flush()#关闭文件 内置了flush功能 f.close()#追加内容 fopen("F:/…

windows无法使用hadoop报错:系统找不到路径

在windows下安装hadoop-3.1.4,进行环境变量配置后&#xff0c;打开window命令行窗口测试hadoop命令&#xff0c;报错&#xff0c;如图所示&#xff1a; 方案&#xff1a;由于JAVA_HOME路径有空格导致&#xff0c;可修改hadoop下\etc\hadoop\hadoop_env.cmd文档中set JAVA_HOME以…

Kubernetes(k8s):如何进行 Kubernetes 集群健康检查?

Kubernetes&#xff08;k8s&#xff09;&#xff1a;如何进行 Kubernetes 集群健康检查&#xff1f; 一、节点健康检查1、使用 kubectl 查看节点状态2、查看节点详细信息3、检查节点资源使用情况 2、Pod 健康检查2.1、 使用 kubectl 查看 Pod 状态2.2、 查看特定 Pod 的详细信息…

JQuery的选择器有哪些?

首先我们需要先了解一下什么是JQuery&#xff0c;并知晓它的概念是什么 概念&#xff1a; 官方概念&#xff1a; jQuery是一个快速&#xff0c;小型且功能丰富的JavaScript库。借助易于使用的API&#xff08;可在多种浏览器中使用&#xff09;&#xff0c;使HTML文档的遍历和操…

Leetcode 228 392

题目 228. 汇总区间 思路 用双指针解决&#xff0c;left指向有序区间的起点&#xff0c;right指向有序区间的终点1&#xff0c;判断right指向的区间是否有序则根据nums[right] right - left nums[left]&#xff1b; 代码 public List<String> summaryRanges(int[] nums…

Oracle数据库常见 问题 或 报错 集合

【报错】字段长度不足 一般字段长度不够时报错&#xff1a; Cause: java.sql.SQLException: ORA-12899: value too large for colum “列名” 【报错】修改字段长度&#xff0c;提示资源正忙 以pl/sql为例&#xff1a; ctrl选中表&#xff0c;在列选项卡下修改字段长度&#x…

基于 java + Springboot + vue +mysql 大学生实习管理系统(含源码)

目录 &#x1f4da; 前言 &#x1f4d1;摘要 &#x1f4d1;实习管理系统的特点 &#x1f4d1;使用架构 &#x1f4da; 总体设计 &#x1f4da; 数据库设计 &#x1f4ac; 系统公告实体属性 &#x1f4ac; 单位成绩实体属性 &#x1f4ac; 学生实体属性 &#x1f4da; 系…

[已解决]Vue3+Element-plus使用el-dialog对话框无法显示

文章目录 问题发现原因分析解决方法 问题发现 点击按钮&#xff0c;没有想要的弹框 代码如下 修改 el-dialog到body中&#xff0c;还是不能显示 原因分析 使用devtool中vue工具进行查看组件结构 原因在于&#xff0c;在一个局部组件(Detail->ElTabPane->…)中使用…