rust语言一些规则学习


最后更新时间2024-05-24

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

map()与for的描述

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

// 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()等方法消费这个新迭代器时,转换操作才真正执行。
    示例:
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循环通常用于有副作用的操作,或者当不需要保留转换结果时。
    示例:
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循环是更合适的选择。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值