Rust 迭代器完全通俗易懂指南(零基础全覆盖)

前言:为什么一定要学迭代器?

但凡你问一位 Rust 老手:Rust 最重要、最常用、最精髓的语法是什么?

答案永远是:迭代器(Iterator)

Rust 中几乎所有集合:数组、动态数组 Vec、哈希表 HashMap、范围序列 1...10,全部都离不开迭代器。迭代器让我们不需要关心下标、开始结束位置、遍历规则,只关心元素本身

简洁、安全、高性能、函数式写法,这就是 Rust 迭代器。

一、for 循环本质:迭代器语法糖

1. 其他语言的循环(靠下标)

例如 JS,必须手动控制索引、长度、边界:

javascript 复制代码
let arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

缺点:要自己管理下标,容易越界、写错索引。

2. Rust 的 for 循环(无下标、纯迭代)

rust 复制代码
let arr = [1, 2, 3];
for v in arr {
    println!("{}",v);
}

Rust 没有下标,直接遍历元素。

重点:Rust 的 for 循环本质就是迭代器的语法糖

数组本身不是迭代器,但是数组实现了 IntoIterator 特征,所以可以自动转为迭代器。

不止数组,这种写法都可以:

rust 复制代码
for i in 1..10 {
    println!("{}", i);
}

二、迭代器最大特点:惰性初始化

Rust 的迭代器是**惰性(lazy)**的:

不使用、不遍历、不消费,就不会执行任何逻辑。

rust 复制代码
let v1 = vec![1, 2, 3];
// 仅仅创建迭代器,什么都不发生
let v1_iter = v1.iter();

// 只有 for 遍历的时候,迭代器才开始工作
for val in v1_iter {
    println!("{}", val);
}

优点:创建迭代器零开销,不占用多余性能。

三、迭代器的核心:Iterator 特征与 next() 方法

1. Iterator 源码

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

只要实现这个特征,就是迭代器。

唯一必须实现的方法:next()

2. next() 作用

  • 每次调用取出一个元素
  • 有值返回 Some(值)
  • 遍历结束返回 None
  • 会改变迭代器内部位置,所以迭代器必须是 mut
rust 复制代码
fn main() {
    let arr = [1, 2, 3];
    let mut arr_iter = arr.into_iter();

    assert_eq!(arr_iter.next(), Some(1));
    assert_eq!(arr_iter.next(), Some(2));
    assert_eq!(arr_iter.next(), Some(3));
    assert_eq!(arr_iter.next(), None);
}

3. for 循环本质(手动模拟)

for 就是不断调用 next,直到 None 跳出循环:

rust 复制代码
let values = vec![1, 2, 3];
{
    let result = match IntoIterator::into_iter(values) {
        mut iter => loop {
            match iter.next() {
                Some(x) => { println!("{}", x); },
                None => break,
            }
        },
    };
    result
}

四、三种迭代器生成方式:iter / iter_mut / into_iter

这三个是新手最容易混淆的,我直白总结:

  1. into_iter:拿走所有权
  2. iter:不可变借用(只读)
  3. iter_mut:可变借用(可修改)
rust 复制代码
fn main() {
    // 1. into_iter:拿走所有权
    let values = vec![1, 2, 3];
    for v in values.into_iter() {
        println!("{}", v)
    }
    // 报错!所有权已经转移
    // println!("{:?}",values);

    // 2. iter:不可变借用
    let values = vec![1, 2, 3];
    let _values_iter = values.iter();
    println!("{:?}", values); // 还能使用

    // 3. iter_mut:可变借用,修改元素
    let mut values = vec![1, 2, 3];
    let mut values_iter_mut = values.iter_mut();
    if let Some(v) = values_iter_mut.next() {
        *v = 0;
    }
    println!("{:?}", values); // [0, 2, 3]
}

返回值区别

  • iter()Some(&T)
  • iter_mut()Some(&mut T)
  • into_iter()Some(T)

五、Iterator vs IntoIterator(彻底分清)

  • Iterator:迭代器本身的特征,必须有 next(),能迭代
  • IntoIterator:普通集合转换成迭代器的特征

一句话:

Iterator 是迭代器;IntoIterator 是能变成迭代器。

六、消费者适配器 & 迭代器适配器

1. 消费者适配器(消耗迭代器)

内部调用 next(),直接把迭代器用完,返回一个结果。

常见:sum、max、min、count、collect、fold

rust 复制代码
fn main() {
    let v1 = vec![1, 2, 3];
    let v1_iter = v1.iter();
    let total: i32 = v1_iter.sum();
    assert_eq!(total, 6);
    // 报错,迭代器已经被 sum 消耗
    // println!("{:?}",v1_iter);
}

2. 迭代器适配器(生成新迭代器)

不消耗迭代器,返回新迭代器,并且全部是惰性的。

常见:map、filter、zip、skip、enumerate

注意:适配器必须搭配消费者才能生效!

rust 复制代码
// 警告:无任何效果,惰性迭代器
v1.iter().map(|x| x + 1);

// 必须 collect 收尾
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();

七、常用迭代器方法实战

1. collect:收集为集合

collect 超级强大,能把迭代器转为 Vec、HashMap 等。

rust 复制代码
use std::collections::HashMap;
fn main() {
    let names = ["sunface", "sunfei"];
    let ages = [18, 18];
    let folks: HashMap<_, _> = names.into_iter().zip(ages.into_iter()).collect();
    println!("{:?}",folks);
}

2. filter:过滤元素

rust 复制代码
struct Shoe {
    size: u32,
    style: String,
}
fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
    shoes.into_iter().filter(|s| s.size == shoe_size).collect()
}

3. zip:合并两个迭代器

把两个迭代器一一配对成元组。

4. enumerate:带索引遍历

rust 复制代码
let v = vec![1u64, 2, 3, 4, 5, 6];
for (i,v) in v.iter().enumerate() {
    println!("第{}个值是{}",i,v)
}

5. 链式调用(经典写法)

rust 复制代码
let v = vec![1u64, 2, 3, 4, 5, 6];
let val = v.iter()
    .enumerate()
    .filter(|&(idx, _)| idx % 2 == 0)
    .map(|(_, val)| val)
    .fold(0u64, |sum, acm| sum + acm);
println!("{}", val);

八、手动实现自己的迭代器

只要实现 Iterator 特征,就能自定义迭代器。

示例:计数器迭代器

rust 复制代码
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> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

复杂链式调用演示:

rust 复制代码
let sum: u32 = Counter::new()
    .zip(Counter::new().skip(1))
    .map(|(a, b)| a * b)
    .filter(|x| x % 3 == 0)
    .sum();
assert_eq!(18, sum);

九、迭代器性能:零成本抽象

很多人以为迭代器慢,实际比手写 for 下标循环更快

官方bench测试结论:

  • 迭代器没有运行时开销
  • 编译器自动优化:循环展开、向量化、消除边界检查
  • 属于 Rust 零成本抽象

结论:放心用迭代器,简洁又快。

十、全文终极总结(背诵版)

  1. for 循环是迭代器语法糖,本质不断调用 next()
  2. 迭代器惰性执行,不消费不运行
  3. Iterator 特征:必须实现 next(),返回 Option
  4. 三种迭代:into_iter(所有权)、iter(只读)、iter_mut(修改)
  5. 适配器:map/filter/zip/enumerate,惰性、生成新迭代器
  6. 消费者:sum/collect/fold,消耗迭代器、出结果
  7. collect 需要手动标注类型,用途极广
  8. 迭代器零成本抽象,性能媲美手写循环
  9. 自定义迭代器:实现 Iterator + 重写 next()
相关推荐
MY_TEUCK9 小时前
【Java 后端】SpringBoot 登录认证与会话跟踪实战(JWT + Filter/Interceptor)
java·开发语言·spring boot
今天长肉了吗9 小时前
银行风控项目踩坑实录:指标跑了6小时,风险评分全挂了
java
QQ2422199799 小时前
基于python+微信小程序的家教管理系统_mh3j9
开发语言·python·微信小程序
随读手机9 小时前
多式联运信息交互平台完整方案(2026版)
java·ai·eclipse·云计算·区块链
沐知全栈开发9 小时前
JavaScript 条件语句
开发语言
RSTJ_16259 小时前
PYTHON+AI LLM DAY THREETY-SEVEN
开发语言·人工智能·python
清水白石0089 小时前
《Python性能深潜:从对象分配开销到“小对象风暴”的破解之道(含实战与最佳实践)》
开发语言·python
Je1lyfish10 小时前
CMU15-445 (2025 Fall/2026 Spring) Project#3 - QueryExecution
linux·c语言·开发语言·数据结构·数据库·c++·算法
许彰午10 小时前
03-二叉树——从递归遍历到非递归实现
java·算法