rust语言一些规则学习

目录

最后更新时间2024-05-24

rust中迭代器的使用(iter().map()与for循环的区别)

map()与for的描述

rust源码中关于iter().map()函数的解释:

rust 复制代码
// core::iter::traits::iterator::Iterator
    /// Takes a closure and creates an iterator which calls that closure on each
    /// element.
    ///
    /// `map()` transforms one iterator into another, by means of its argument:
    /// something that implements [`FnMut`]. It produces a new iterator which
    /// calls this closure on each element of the original iterator.
    ///
    /// If you are good at thinking in types, you can think of `map()` like this:
    /// If you have an iterator that gives you elements of some type `A`, and
    /// you want an iterator of some other type `B`, you can use `map()`,
    /// passing a closure that takes an `A` and returns a `B`.
    ///
    /// `map()` is conceptually similar to a [`for`] loop. However, as `map()` is
    /// lazy, it is best used when you're already working with other iterators.
    /// If you're doing some sort of looping for a side effect, it's considered
    /// more idiomatic to use [`for`] than `map()`.
    ///
    /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// let mut iter = a.iter().map(|x| 2 * x);
    ///
    /// assert_eq!(iter.next(), Some(2));
    /// assert_eq!(iter.next(), Some(4));
    /// assert_eq!(iter.next(), Some(6));
    /// assert_eq!(iter.next(), None);
    /// ```
    ///
    /// If you're doing some sort of side effect, prefer [`for`] to `map()`:
    ///
    /// ```
    /// # #![allow(unused_must_use)]
    /// // don't do this:
    /// (0..5).map(|x| println!("{x}"));
    ///
    /// // it won't even execute, as it is lazy. Rust will warn you about this.
    ///
    /// // Instead, use for:
    /// for x in 0..5 {
    ///     println!("{x}");
    /// }
    /// ```
    fn map<B, F>(self, f: F) -> Map<Self, F>
    where
        Self: Sized,
        F: FnMut(Self::Item) -> B,
    {
        Map::new(self, f)
    }

上述官方解释比较难以理解,这里解释一下官方的解释:
iter().map()for循环都是用来遍历集合(如Vec、数组或其他迭代器)的常用方法,但它们在使用场景、目的和返回值方面有所不同。

  1. iter().map()
    iter().map()是Rust标准库提供的迭代器适配器方法之一,用于对集合中的每个元素应用一个函数,生成一个新的迭代器,该迭代器产生的是原函数应用结果的序列。它主要用于数据转换,且不会修改原集合。map操作是惰性的,即直到你通过collect()for_each()等方法消费这个新迭代器时,转换操作才真正执行。
    示例:
rust 复制代码
let numbers = vec![1, 2, 3, 4];
let doubled: Vec<i32> = numbers.iter().map(|&x| x * 2).collect();
// doubled 现在是 vec![2, 4, 6, 8]
  1. for循环
    for循环则是一种更通用的迭代结构,它可以遍历任何实现了IntoIterator特质的集合。for循环允许你对集合中的每个元素执行一系列操作,这些操作可以是任意的,包括打印、修改集合内容、计算某个值或调用函数等。与map()不同,for循环通常用于有副作用的操作,或者当不需要保留转换结果时。
    示例:
rust 复制代码
let mut numbers = vec![1, 2, 3, 4];
for num in &mut numbers {
    *num *= 2;
}
// numbers 现在是 vec![2, 4, 6, 8]

区别

目的: iter().map()主要用于无副作用的数据转换,并生成新的数据序列;而for循环适用于任何需要遍历并可能带有副作用操作的场景。
返回值: map返回一个新的迭代器,其中包含转换后的值;for循环没有直接返回值,主要用于执行过程中的操作。
惰性与立即执行: map是惰性的,需要进一步的动作(如collect)来实际执行转换;for循环则是立即执行的。
修改原集合: map不修改原集合,而for循环可以通过可变引用修改集合内容。

选择哪种方式取决于你的具体需求:是否需要保留原集合、是否需要进行数据转换、以及是否执行有副作用的操作。

总结

iter().map() 主要用于将数据集中的每个元素转换为另一个形式,创建出一个新的数据集(不改变原数据),适用于无副作用的数据转换场景。比如,将一个整数集合转换为对应的字符串集合,或对每个元素应用某种计算规则得到新的值并创建新的集合。

for 循环则更加灵活,既可以用作简单的遍历查看元素,也可以用来直接修改原数据集中的元素。当你需要对集合中的每个元素执行可能包含副作用的操作(如修改元素、打印输出 、基于当前元素影响外部状态等)时,for循环是更合适的选择。

相关推荐
PRINT!1 分钟前
RabbitMQ实战项目(含代码仓库地址+视频教程地址)基本篇已更新完结,高级篇持续更新中
java·分布式·后端·微服务·rabbitmq
gAlAxy...20 分钟前
MyBatis-Plus 核心 CRUD 操作全解析:BaseMapper 与通用 Service 实战
java·开发语言·mybatis
开开心心就好24 分钟前
一键加密隐藏视频,专属格式播放工具
java·linux·开发语言·网络·人工智能·macos
CUC-MenG1 小时前
Codeforces Round 1079 (Div. 2)A,B,C,D,E1,E2,F个人题解
c语言·开发语言·数学·算法
阿里嘎多学长1 小时前
2026-02-07 GitHub 热点项目精选
开发语言·程序员·github·代码托管
小心草里有鬼1 小时前
VMware虚拟机扩容
linux·后端·centos·vim
Anastasiozzzz1 小时前
Java异步编程:CompletableFuture从入门到底层实现
java·开发语言
九.九2 小时前
高性能算子库 ops-nn 的底层架构:从调度到指令的极致优化
开发语言
比奇堡派星星2 小时前
sed命令
linux·运维·服务器·开发语言
船神丿男人2 小时前
C++:STL string(一)
开发语言·c++