2024 Rust现代实用教程Iterator迭代器

文章目录

  • 一、迭代与循环
    • 1.循环
    • 2.迭代iteration
    • 3.区别
  • 二、Intoiterator、Iterator和Iter之间的关系
    • 1.Intolterator
    • 2.Iterator Trait
    • 3. 源码中经常出现的iter
  • 三、获取迭代器的三种方法iter(),iter_mut()和into_iter()
    • 1.iter()方法
    • 2.iter_mut()方法
    • 3.into_iter()方法---尽量写
  • 四、自定义类型实现iter(),iter_mut()和into_iter()
  • 参考

一、迭代与循环

1.循环

定义:循环是一种控制流结构,它会反复执行一组语句,直到满足某个条件。
控制条件:循环通常包含一个条件表达式,只有在条件为真时,循环体中的语句才会执行。
退出条件:循环执行直到条件不再满足,或者通过break、语句显式中断循环。
使用场景:适用于需要反复执行某个操作直到满足某个条件的情况。

2.迭代iteration

·定义:选代是对序列中的元素进行逐个访问的过程。
·控制条件:迭代通常使用迭代器(lterator)来实现,迭代器提供了对序列元素的访问和操作。
·退出条件:通常不需要显式的退出条件,迭代器会在处理完所有元素后自动停止。
·使用场景:适用于需要遍历数据结构中的元素的情况,例如数组、切片、集合等。

3.区别

·1.循环是一种控制流结构,它反复执行一组语句。
·2.送代是对序列中的元素进行逐个访问的过程,通常使用迭代器实现。
·3.循环可以是有限的(通过设置退出条件)或无限的(使用loop)关键字)。
·4.迭代器提供了一种更抽象的方式来处理序列,使得代码更具可读性和灵活性。
在Rust中,循环和迭代性能的差距可能会取决于具体的使用情况和编译器的优化。绝大多数情况下,Rust的迭代器是经过优化的,可以达到或接近手动编写循环的性能水平。

// &[i32] &Vec
// loop
fn sum_with_loop(arr: &[i32]) -> i32 {let mut sum = 0;for &item in arr {sum += item;}sum
}// iter
fn sum_with_iter(arr: &[i32]) -> i32 {arr.iter().sum()
}fn main() {const ARRAY_SIZE: usize = 10000;let array: Vec<i32> = (1..=ARRAY_SIZE as i32).collect();let sum1 = sum_with_loop(&array);println!("sum loop {}", sum1);let sum2 = sum_with_iter(&array);println!("sum loop {}", sum2);
}

编译及运行:

▶ cargo runCompiling ch5_iter_loop v0.1.0 (/home/wangji/code/rust/2024_rust/rust_project/ch4_iter_loop)Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.20sRunning `target/debug/ch5_iter_loop`
sum loop 50005000
sum loop 50005000

二、Intoiterator、Iterator和Iter之间的关系

1.Intolterator

Intolterator是一个RustTrait,它定义了一种将类型转换为迭代器的能力。
该Trait包含一个方法into_iter,该方法返回一个实现了IteratorTrait的迭代器。

通常,当你有一个类型,希望能够对其进行迭代时,你会实现IntolteratorTrait来提供将该类型转换为迭代器的方法。

2.Iterator Trait

Iterator是Rust标准库中的Trait,定义了一种访问序列元素的方式。
·它包含了一系列方法,如next、map、filter、sum、等,用于对序列进行不同类型的操作。

·通过实现Iterator丶Trait,你可以创建自定义的迭代器,以定义如何迭代你的类型中的元素。

pub trait Iterator{
type Item;
fn next(&mut self) -> Option<Self::Item>;
}

3. 源码中经常出现的iter

·Iter是IteratorTrait的一个具体实现,通常用于对集合中的元素进行迭代。
·在Rust中,你会经常看到Iter,特别是在对数组、切片等集合类型进行迭代时。
·通过lntolteratorTrait,你可以获取到一个特定类型的迭代器,比如Iter,然后可以使用IteratorTrait的方法进行操作。

fn main() {// veclet v = vec![1, 2, 3, 4, 5]; // intoIterator 特质 into_iter// 转换为迭代器let iter = v.into_iter(); // move 所有权转移 类似ppt中的Iter Iterator的特质对象let sum: i32 = iter.sum();println!("sum: {}", sum);// println!("{:?}", v)// arraylet array = [1, 2, 3, 4, 5];let iter: std::slice::Iter<'_, i32> = array.iter();//所有权没有转移let sum: i32 = iter.sum();println!("sum: {}", sum);println!("{:?}", array);// charslet text = "hello, world!";let iter = text.chars();//所有权没有转移// 等价于let uppercase:String = iter.map(|c| c.to_ascii_uppercase()).collect();// collect表示迭代器的下一个, <String>表示返回的类型是Stringlet uppercase = iter.map(|c| c.to_ascii_uppercase()).collect::<String>();println!("uppercase: {}", uppercase);println!("{:?}", text);
}

编译及运行

▶ cargo runCompiling ch2_intoiterator_iterator_iter v0.1.0 (/home/wangji/code/rust/2024_rust/rust_project/ch5_intoiterator_iterator_iter)Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.04sRunning `target/debug/ch2_intoiterator_iterator_iter`
sum: 15
sum: 15
[1, 2, 3, 4, 5]
uppercase: HELLO, WORLD!
"hello, world!"

三、获取迭代器的三种方法iter(),iter_mut()和into_iter()

1.iter()方法

iter()方法返回一个不可变引用的迭代器,用于只读访问集合的元素。
该方法适用于你希望在不修改集合的情况下迭代元素的场景。

2.iter_mut()方法

iter_mut()方法返回一个可变引用的迭代器,用于允许修改集合中的元素。
该方法适用于你希望在迭代过程中修改集合元素的场景。

3.into_iter()方法—尽量写

into_iter()方法返回一个拥有所有权的迭代器,该迭代器会消耗集合本身,将所有权转移到迭代器。

该方法适用于你希望在迭代过程中拥有集合的所有权,以便进行消耗性的操作,如移除元素。

fn main() {let vec = vec![1, 2, 3, 4, 5];// iter()for &item in vec.iter() {println!("{}", item);}println!("{:?}", vec);// 可变引用let mut vec = vec![1, 2, 3, 4, 5];for item in vec.iter_mut() {*item *= 2;}// 所有权转移println!("{:?}", vec);let vec = vec![1, 2, 3, 4, 5];for item in vec.into_iter() {println!("{}", item);}// println!("{:?}", vec);
}

编译加运行

▶ cargo runCompiling ch3_iter v0.1.0 (/home/wangji/code/rust/2024_rust/rust_project/ch6_iter)Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.14sRunning `target/debug/ch3_iter`
1
2
3
4
5
[1, 2, 3, 4, 5]
[2, 4, 6, 8, 10]
1
2
3
4
5

四、自定义类型实现iter(),iter_mut()和into_iter()

参考

  • 2024 Rust现代实用教程

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

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

相关文章

VSCode进阶之路

VSCode进阶之路&#xff1a;从入门到高效率开发 &#x1f680; Hey&#xff0c;朋友们好&#xff01;还在为VSCode的海量功能感到眼花缭乱吗&#xff1f;咱们一起来解锁VSCode的超神技能吧&#xff01; 开篇碎碎念 &#x1f3af; 第一次用VSCode时&#xff0c;就像个闯入魔法世…

专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。

已经顺利读研一段时间&#xff0c;回顾一下考研还是历历在目。应群里学弟要求&#xff0c;回忆总结一下自己考研经历&#xff0c;希望对大家复习有帮助。总分400&#xff0c;专业课855信号与系统130&#xff08;犯了低级错误&#xff0c;计算出现问题&#xff0c;大家专业好好准…

Self-Lengthen:阿里千问开源提升 LLM 长文本生成能力的训练框架

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

双向链表及如何使用GLib的GList实现双向链表

双向链表是一种比单向链表更为灵活的数据结构&#xff0c;与单向链表相比可以有更多的应用场景&#xff0c;本文讨论双向链表的基本概念及实现方法&#xff0c;并着重介绍使用GLib的GList实现单向链表的方法及步骤&#xff0c;本文给出了多个实际范例源代码&#xff0c;旨在帮助…

理解前端打包工具树摇优化:如何通过import,export静态分析移除未使用的代码

理解树摇优化&#xff1a;如何通过静态分析移除未使用的代码 在现代前端开发中&#xff0c;代码的体积和性能至关重要。随着应用程序日益复杂&#xff0c;优化打包过程、减少未使用代码的大小成为了一个迫切的需求。树摇优化&#xff08;Tree Shaking&#xff09;就是为了解决…

【rust实战】rust博客系统4_连接数据库及查询数据

问题 回答 解释如何连接数据库1.在Cargo.toml中添加 mysql 依赖项 mysql "21.0.0" 2.在src/db/db.rs中写连接数据库的代码 use mysql::*; use mysql::prelude::* pub fn init_pool() -> Result<Pool> { let url "mysql://root…

C++笔试题之实现一个定时器

一.定时器&#xff08;timer&#xff09;的需求 1.执行定时任务的时&#xff0c;主线程不阻塞&#xff0c;所以timer必须至少持有一个线程用于执行定时任务 2.考虑到timer线程资源的合理利用&#xff0c;一个timer需要能够管理多个定时任务&#xff0c;所以timer要支持增删任务…

计算从位置 x 到 y 的最少步数

问题描述 小F正在进行一个 AB 实验&#xff0c;需要从整数位置 x 移动到整数位置 y。每一步可以将当前位置增加或减少&#xff0c;且每步的增加或减少的值必须是连续的整数&#xff08;即每步的移动范围是上一步的 -1&#xff0c;0 或 1&#xff09;。首末两步的步长必须是 1。…

【Java笔记】1-JDK/JRE/JVM是个啥?

JDK、JRE、JVM可以说是入门必须了解的三个词汇 先说全称 JDK&#xff1a;Java Development Kit&#xff0c;Java开发工具包 JRE&#xff1a;Java Runtime Environment&#xff0c;Java运行环境 JVM&#xff1a;Java Virtual Machine&#xff0c;Java虚拟机 再说关系 JVM⊆J…

C++ 报错 first defined here XXXXX multiple definition of XXXX

这个报错是重定义 1、首先检查下是不是真的重定义了&#xff0c;检查下报错提示的函数&#xff0c;以及提示的路径位置 2、头文件被多次包含时&#xff0c;没有设置只包含一次 头文件用宏定义包含&#xff0c;注意宏定义别重复 #ifndef XXX_H #define XXX_H// 函数声明和定…

c语言-进位计数制

文章目录 一、进位计数制是什么&#xff1f;二、c语言1.二进制转十进制2.十进制转二进制 一、进位计数制是什么&#xff1f; 进位计数制简称进制&#xff0c;是人类用于计算数量的基本规则。 可使用数字符号的数目称为基数或底数&#xff0c;基数个数为n个&#xff0c;即可称n…

HTML 基础标签——结构化标签<html>、<head>、<body>

文章目录 1. <html> 标签2. <head> 标签3. <body> 标签4. <div> 标签5. <span> 标签小结 在 HTML 文档中&#xff0c;使用特定的结构标签可以有效地组织和管理网页内容。这些标签不仅有助于浏览器正确解析和渲染页面&#xff0c;还能提高网页的可…

中国计算机学会推荐国际学术会议和期刊目录- 2022

官网只给了PDF文件&#xff0c;我转换成了excel文件&#xff0c;便于筛选和查找。 excel文件&#xff1a;GitHub

【算法赌场】区间合并

区间问题 区间问题的引入 数学上&#xff0c;用两个数字可以确定数轴上的一个区间&#xff0c;较小的数字叫做区间的左端点&#xff0c;也叫区间起点&#xff0c;较大的数字叫做区间的右端点&#xff0c;也叫区间终点。 在算法竞赛中&#xff0c;很多题目是以区间为单位去进行…

给定开始日期时间结束日期时间、间隔得到符合条件的序列pandas.timedelta_range()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 给定开始日期时间 结束日期时间、间隔 得到符合条件的序列 pandas.timedelta_range() [太阳]选择题 以下代码执行后&#xff0c;delta中包含的时间差序列的个数是多少&#xff1f; import pa…

【AI工作流】FastGPT - 深入解析FastGPT工作流编排:从基础到高级应用的全面指南

文章目录 一、工作流编排概述二、FastGPT的节点类型1. 基础功能插件(1) 文本输出(2) 功能调用(3) 工具(4) 外部调用(5) 其他 2. 系统插件3. 团队插件 三、工作流中的流向结语 在当今快速发展的人工智能领域&#xff0c;工作流编排的能力已成为提升用户体验和应用效率的关键因素…

qt QAction详解

1、概述 QAction是Qt框架中的一个抽象类&#xff0c;用于表示用户界面中的一个动作&#xff08;action&#xff09;。这些动作可以绑定到菜单项、工具栏按钮或快捷键上&#xff0c;提供了一种灵活的方式来处理用户交互。QAction不仅包含了动作的名称、图标、提示信息等属性&am…

MRCTF2020:你传你ma呢

文件上传题先判断黑白名单过滤&#xff0c;先传个最简单的木马 这里上传不了php文件&#xff0c;猜测可能是对php文件进行了过滤&#xff0c;将文件改为任意后缀这里改为.abc 还是上传不成功&#xff0c;猜测可能对MIME也做了过滤&#xff0c;将Content-Type更改为image/jpeg再…

CSS中的优先级和优先权

层叠的规则:后出现的样式会覆盖前面设置的样式 p {color: red; } ​ p {color: blue; } 比如这段代码生效是颜色是blue. 若是不同选择器之间发生了样式冲突,则描述更为具体的那个选择器具有更高的优先级,比如id选择器 > 类选择器 > 标签选择器这低优先级是无法覆盖高优…

LeetCode (206单链表反转)

目录 题目描述: 代码: 第一种: 第二种: 第三种: 第四种: 第五种: 主函数: ListNode类: 题目描述: 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3…