目录

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循环是更合适的选择。

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
Swift社区34 分钟前
从表格到序列:Swift 如何优雅地解 LeetCode 251 展开二维向量
开发语言·leetcode·swift
hweiyu0038 分钟前
Python从入门到精通全套视频教程免费
开发语言·python
洛可可白1 小时前
Spring Boot中自定义注解的创建与使用
java·spring boot·后端
唐人街都是苦瓜脸2 小时前
Java RPC 框架是什么
java·开发语言·rpc
追逐时光者2 小时前
一款 .NET 开源、免费、轻量级且非侵入性的防火墙软件
后端·.net
黑不溜秋的2 小时前
Ubuntu24.04 编译 Qt 源码
开发语言·qt
ALex_zry2 小时前
C++17模板编程与if constexpr深度解析
开发语言·c++·性能优化
AugustShuai2 小时前
API-标准controller接口
开发语言·json·设计规范·post·标准接口
幻想趾于现实3 小时前
C# Winform 入门(15)之制作二维码和拼接(QR)
开发语言·c#·winform
wniuniu_3 小时前
Pow工作量证明是啥
开发语言·区块链·php