15 rust基础 iterator-迭代器

Rust 迭代器 (Iterator)

1️⃣ 什么是迭代器?

在 Rust 中,迭代器是一种对象,它实现了 Iterator 特征(trait)。最常见的用法是对集合进行遍历,比如数组、向量、HashMap 等。

核心定义:

pub trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
    // 其他方法(map, filter, collect等)
}
  • type Item:迭代器要产生的元素类型。
  • next:每次调用都会返回 Some(Item)(下一个元素)或 None(迭代结束)。

示例:

let v = vec![1, 2, 3];
let mut iter = v.iter();

assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None); // 迭代结束

2️⃣ 常见的迭代器方法

🌟 基础方法

  • next():逐个取值。
  • collect():将迭代器转化为集合类型,如 VecHashMap 等。
  • count():计算迭代器中元素的个数。
  • last():返回迭代器中最后一个元素。
  • ...
let v = vec![1, 2, 3];
let count = v.iter().count();
assert_eq!(count, 3);

🎨 转换方法

  • map():对每个元素进行映射,生成一个新的惰性迭代器。
let v = vec![1, 2, 3];
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
assert_eq!(doubled, vec![2, 4, 6]);
  • filter():过滤元素,只保留满足条件的项。
let v = vec![1, 2, 3, 4];
let evens: Vec<i32> = v.iter().filter(|&&x| x % 2 == 0).collect();
assert_eq!(evens, vec![2, 4]);
  • flat_map():将嵌套的迭代器扁平化。
let v = vec![vec![1, 2], vec![3, 4]];
let flattened: Vec<i32> = v.into_iter().flat_map(|x| x).collect();
assert_eq!(flattened, vec![1, 2, 3, 4]);

🚀 消费方法(消费惰性迭代器)

  • sum():求和。
  • product():计算所有元素的乘积。
  • fold():聚合操作,接受初始值和闭包。
let v = vec![1, 2, 3];
let sum: i32 = v.iter().sum();
assert_eq!(sum, 6);

let product: i32 = v.iter().product();
assert_eq!(product, 6);

let sum = v.iter().fold(0, |acc, &x| acc + x);
assert_eq!(sum, 6);

3️⃣ 惰性计算 (Lazy Evaluation)

迭代器是惰性的,这意味着仅在需要时才执行计算。例如:

let v = vec![1, 2, 3];
v.iter().map(|x| println!("{}", x)); // 什么都不会打印

v.iter().map(|x| println!("{}", x)).collect::<Vec<_>>(); // 此时才执行

只有在终结方法(如 collect)调用时,计算才真正发生。


4️⃣ 创建迭代器

  • 数组/向量iter()iter_mut()into_iter()
let v = vec![1, 2, 3];
let iter = v.iter(); // 不可变借用
let iter_mut = v.iter_mut(); // 可变借用
let into_iter = v.into_iter(); // 消耗集合
  • 范围 (Range)
for i in 1..=5 {
    print!("{} ", i); // 输出 1 2 3 4 5
}

let factorial: i32 = (1..=5).product();
assert_eq!(factorial, 120);
  • 手动实现迭代器
struct Counter {
    count: u32,
}

impl Counter {
    fn new() -> Counter {
        Counter { count: 0 }
    }
}

impl Iterator for Counter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        self.count += 1;
        if self.count <= 5 {
            Some(self.count)
        } else {
            None
        }
    }
}

let mut counter = Counter::new();
while let Some(n) = counter.next() {
    println!("{}", n);
}

5️⃣ 组合迭代器链

迭代器可以通过链式调用组合使用:

let v = vec![1, 2, 3, 4];
let result: Vec<i32> = v.into_iter()
    .filter(|&x| x % 2 == 0)
    .map(|x| x * 10)
    .collect();

assert_eq!(result, vec![20, 40]);

迭代器遵循原则:

  1. 惰性求职:不会立即进行任何计算或操作,直到调用终结方法。
  2. 所有权和借用检查:迭代器严格遵守所有权和借用规则,迭代器的生命周期与底层数据相关联,确保数据的安全访问。
    3.链式调用:支持链式调用,多个迭代方法组合使用,包括转换方法和终结方法。
    4.高效内存管理:惰性求值使用时才进行遍历操作。
    5.抽象和通用性:通过Tierator trait 实现抽象和通用性。提高代码的重用性和模块化。

🎯 总结

  1. 迭代器是惰性的,只有在终结方法调用时才执行。
  2. 核心方法:
    • 转换方法:mapfilterflat_map
    • 终结方法:collectcountsum
  3. 迭代器链 可以组合多个方法,让数据处理更简洁。
  4. 手动实现迭代器 时需要实现 Iterator 特征,并定义 next()
posted @ 2025-03-15 00:19  代码世界faq  阅读(53)  评论(0)    收藏  举报