Rust 集合 + 迭代器完整详解

Rust 集合 + 迭代器完整详解

涵盖 :标准库容器(Vec、HashMap、BTreeMap 等)、Iterator trait、适配器、消费者方法

重点:集合选型对比、迭代器惰性机制、链式组合写法


目录

  1. 标准库集合容器
  2. 迭代器 Iterator 完整核心(#第二部分迭代器 iterator-完整核心)
  3. [集合 + 迭代器高频综合场景](#集合 + 迭代器高频综合场景 "#%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86%E9%9B%86%E5%90%88%E8%BF%AD%E4%BB%A3%E5%99%A8%E9%AB%98%E9%A2%91%E7%BB%BC%E5%90%88%E5%9C%BA%E6%99%AF")
  4. 易错点
  5. 速记口诀

第一部分:标准库集合容器(std::collections)

所有集合共性

  1. 底层数据存,集合变量本体很小,栈存指针/元数据
  2. 拥有所有权,离开作用域自动释放堆内存
  3. 全部实现 IntoIterator,可 for 循环遍历

一、Vec 动态数组(最常用)

底层结构
rust 复制代码
struct Vec<T> {
    ptr: *mut T,
    len: usize,
    cap: usize,
}

栈存三元组,元素在堆,自动扩容。

基础操作
rust 复制代码
// 创建
let mut v = Vec::new();
let mut v = vec![1, 2, 3];
let mut v = Vec::with_capacity(10); // 预分配容量,减少扩容

// 增删改查
v.push(4);          // 尾部追加
v.pop();            // 弹出末尾
v.insert(0, 0);     // 指定下标插入(后面元素后移,性能差)
v.remove(0);        // 删除下标元素
v[0];               // 下标访问,越界 panic
v.get(0);           // 返回 Option<&T>,安全不崩溃

// 遍历
for x in &v {}       // 借用遍历,不转移所有权
for x in v {}        // 所有权转移,遍历后 v 失效

适用场景:有序、频繁尾部增删、随机下标访问


二、VecDeque 双端队列

支持头部、尾部 O(1) 增删,中间删除仍慢;适合队列、缓冲区、滑动窗口。

rust 复制代码
use std::collections::VecDeque;
let mut deq = VecDeque::new();
deq.push_back(1);
deq.push_front(0);
deq.pop_front(); // 出队头

三、LinkedList 双向链表

随机访问 O(n),仅头尾、拆分合并效率高;极少日常使用,适合大量中间插入删除且不随机下标场景。


四、HashMap<K,V> 哈希表(键值无序)

底层:哈希数组 + 链地址法冲突处理,无序存储。

约束K 必须实现 Eq + Hash

rust 复制代码
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert("name", "zhangsan");

// 查询
if let Some(v) = map.get("name") {}
map.entry("age").or_insert(18); // 不存在则插入默认值

// 遍历键/值/键值对
for (k, v) in &map {}

适用:快速按 Key 查找、去重、映射关系


五、BTreeMap<K,V> 有序二叉树映射

底层红黑树,按键自动升序排列

约束K: Ord(可比较排序)

优点 :可区间查询 range,遍历有序

缺点:读写性能弱于 HashMap

rust 复制代码
use std::collections::BTreeMap;
let mut tree = BTreeMap::new();
tree.insert(3, "c");
tree.insert(1, "a");
// 遍历自动 1,3 有序
for (k, v) in &tree {}
// 区间查询 2..=5
for (k, _) in tree.range(2..=5) {}

六、HashSet 哈希集合(去重,无序)

等价 HashMap<T, ()>,仅存键无值,自动去重。

约束T: Eq + Hash

rust 复制代码
use std::collections::HashSet;
let mut set = HashSet::new();
set.insert(1);
set.contains(&1); // 判断存在
set.remove(&1);

七、BTreeSet 有序集合

等价 BTreeMap<T,()>,元素自动排序,支持区间遍历。


集合快速选型对照表

容器 有序 随机下标 头尾增删 查找速度 典型用途
Vec 插入有序 ✅ O(1) 尾快头慢 O(n) 遍历 列表、缓冲区
VecDeque 插入有序 ✅ O(1) O(n) 队列、滑动窗口
HashMap 无序 - O(1) 哈希 KV 映射、缓存
BTreeMap Key 升序 - O(log n) 有序 KV、区间查询
HashSet 无序 - O(1) 去重、成员判断
BTreeSet 升序 - O(log n) 有序去重、范围筛选

第二部分:迭代器 Iterator 完整核心

1. 核心 trait:Iterator

所有迭代器都实现 std::iter::Iterator,唯一必需方法:

rust 复制代码
trait Iterator {
    type Item; // 每次产出的元素类型
    fn next(&mut self) -> Option<Self::Item>;
}
  • next() 返回 Some(元素) 还有值;返回 None 迭代结束
  • 迭代器是惰性:不调用 next 不计算、不产生元素

2. 生成迭代器三种方式

(1).iter():借用迭代,产出 &T

集合不变,遍历只读

rust 复制代码
let v = vec![1, 2, 3];
for x in v.iter() { println!("{}", x); } // x:&i32
(2).iter_mut():可变借用,产出 &mut T

可修改集合内元素

rust 复制代码
let mut v = vec![1, 2];
for x in v.iter_mut() { *x *= 2; }
(3).into_iter():获取所有权,产出 T,遍历后原集合失效
rust 复制代码
let v = vec![1, 2];
for x in v { // 隐式调用 into_iter()
    println!("{}", x);
}
// v 已 move 失效
自动推导 for 循环规则
写法 等价方法
for x in &集合 .iter()
for x in &mut 集合 .iter_mut()
for x in 集合 .into_iter()

3. 迭代器适配器(链式方法,惰性)

适配器返回新迭代器,不立即计算,仅调用 next 时执行逻辑。

map:转换每个元素
rust 复制代码
let v: Vec<i32> = vec![1, 2, 3].iter().map(|x| x * 2).collect();
// collect() 消费迭代器,收集到集合
filter:过滤,返回 true 的元素
rust 复制代码
let evens: Vec<_> = (1..=10).filter(|x| x % 2 == 0).collect();
flat_map:展开嵌套迭代(二维转一维)
rust 复制代码
let data = vec![vec![1, 2], vec![3, 4]];
let all: Vec<_> = data.iter().flat_map(|arr| arr).collect();
// [1,2,3,4]
take / skip:截取、跳过前 N 个
rust 复制代码
(1..=10).take(3);  // 1,2,3
(1..=10).skip(2);  // 3,4..10
fold:聚合计算(归约)
rust 复制代码
let sum = (1..=10).fold(0, |acc, x| acc + x); // 累加总和
any / all:判断是否存在/全部满足条件
rust 复制代码
(1..=5).any(|x| x > 3);  // true
(1..=5).all(|x| x < 10); // true
zip:两个迭代器配对
rust 复制代码
let a = [1, 2];
let b = ["a", "b"];
let pairs: Vec<_> = a.iter().zip(b.iter()).collect();
// [(1,"a"), (2,"b")]

4. 消费者方法(消耗迭代器,生成结果)

调用后迭代器失效,执行计算:

方法 说明
collect() 收集到 Vec/HashMap/BTreeSet 等集合(需标注类型或推导)
fold() 自定义聚合
sum() / product() 求和、乘积
max() / min() 最值,返回 Option
count() 统计元素个数
last() 取最后一个元素

5. 范围迭代器 Range

a..b 左闭右开,a..=b 闭区间,轻量迭代器无堆分配

rust 复制代码
for i in 1..5 {}    // 1,2,3,4
for i in 1..=5 {}   // 1,2,3,4,5

6. 实现自定义迭代器(简易示例)

rust 复制代码
// 自定义计数器迭代器
struct Counter {
    max: i32,
    current: i32,
}

impl Iterator for Counter {
    type Item = i32;
    fn next(&mut self) -> Option<Self::Item> {
        if self.current < self.max {
            let val = self.current;
            self.current += 1;
            Some(val)
        } else {
            None
        }
    }
}

let cnt = Counter { max: 3, current: 0 };
let res: Vec<_> = cnt.collect(); // [0,1,2]

7. IntoIterator trait(让类型可被 for 遍历)

所有能 for x in T 的类型都实现 IntoIterator

  • Vec、数组、HashMap、Range、Option、Result
rust 复制代码
// Option 也可迭代(0 或 1 个元素)
let opt = Some(10);
for x in opt { println!("{}", x); }

8. 迭代器核心特性总结

  1. 惰性:适配器仅组装逻辑,next/collect 才执行
  2. 零开销抽象:编译器会优化循环,手写 for 循环性能一致
  3. 所有权可控:iter/iter_mut/into_iter 三种借用模式
  4. 链式组合:map+filter+take 简洁替代多层循环

第三部分:集合 + 迭代器高频综合场景

1. Vec 过滤再映射收集

rust 复制代码
let nums = vec![1, 2, 3, 4];
let double_even: Vec<_> = nums
    .iter()
    .filter(|&&x| x % 2 == 0)
    .map(|&x| x * 2)
    .collect();

2. HashMap 遍历过滤插入新 map

rust 复制代码
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert(1, "one");
let filtered: HashMap<_, _> = map
    .iter()
    .filter(|(&k, _)| k > 0)
    .map(|(&k, &v)| (k, v))
    .collect();

3. BTreeMap 有序区间遍历

rust 复制代码
use std::collections::BTreeMap;
let mut tree = BTreeMap::new();
tree.insert(1, "a");
tree.insert(5, "e");
tree.insert(3, "c");
// 只取 2~4 之间的 key
for (k, v) in tree.range(2..=4) {
    println!("{} {}", k, v);
}

第四部分 易错点

⚠️ 以下易错点需特别注意

  1. iter() 产出引用 ,map 直接使用需解引用 |&x|
  2. collect() 需要类型提示,编译器无法自动推断目标集合
  3. 迭代器惰性:只写 map/filter 不 collect/count 不会执行任何逻辑
  4. into_iter 遍历集合后原变量所有权转移,不能再使用
  5. HashMap 无序,需要有序遍历改用 BTreeMap
  6. Vec 中间 remove 性能差,大量中间删除优先 LinkedList
  7. 迭代器不能重复使用,消费一次后内部状态走完,next 永远返回 None

速记口诀

python 复制代码
容器七类分有序无序,Vec 动态数组最常用;
哈希无序树有序,队列双端 VecDeque;
迭代核心 next 返回 Option,惰性适配器不运算;
iter 借、iter_mut 改、into_iter 拿走所有权;
map 转换 filter 过滤,fold 聚合 collect 收集;
range 区间轻量迭代,链式写法替代多层循环。
相关推荐
杨利杰YJlio1 小时前
Codex桌面客户端上手:项目、插件与自动化实战
前端·后端
常铭1 小时前
【Java基础】01-HashMap的底层原理
后端·面试
幼儿园技术家2 小时前
实现 GEO 监控:从多引擎探测到优化闭环
前端·后端
掘金者阿豪2 小时前
微信小程序虚拟支付与广告转化回传实战记录
后端
ping某3 小时前
专栏-null 和 undefined 到底是什么?
前端·javascript·后端
神奇小汤圆3 小时前
别再只会用ArrayList了!Java集合框架的性能天花板到底在哪?
后端
神奇小汤圆3 小时前
Dubbo 的 SPI 和 JDK 的 SPI 有什么区别?
后端
叫我少年4 小时前
C# 字符串基础
后端
道友可好4 小时前
从今天开始:你的第一个 Harness Engineering 实践
前端·人工智能·后端