Rust 集合 + 迭代器完整详解
涵盖 :标准库容器(Vec、HashMap、BTreeMap 等)、Iterator trait、适配器、消费者方法
重点:集合选型对比、迭代器惰性机制、链式组合写法
目录
- 标准库集合容器
- 迭代器 Iterator 完整核心(#第二部分迭代器 iterator-完整核心)
- [集合 + 迭代器高频综合场景](#集合 + 迭代器高频综合场景 "#%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")
- 易错点
- 速记口诀
第一部分:标准库集合容器(std::collections)
所有集合共性
- 底层数据存堆,集合变量本体很小,栈存指针/元数据
- 拥有所有权,离开作用域自动释放堆内存
- 全部实现
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. 迭代器核心特性总结
- 惰性:适配器仅组装逻辑,next/collect 才执行
- 零开销抽象:编译器会优化循环,手写 for 循环性能一致
- 所有权可控:iter/iter_mut/into_iter 三种借用模式
- 链式组合: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);
}
第四部分 易错点
⚠️ 以下易错点需特别注意
iter()产出引用 ,map 直接使用需解引用|&x|- collect() 需要类型提示,编译器无法自动推断目标集合
- 迭代器惰性:只写 map/filter 不 collect/count 不会执行任何逻辑
- into_iter 遍历集合后原变量所有权转移,不能再使用
- HashMap 无序,需要有序遍历改用 BTreeMap
- Vec 中间 remove 性能差,大量中间删除优先 LinkedList
- 迭代器不能重复使用,消费一次后内部状态走完,next 永远返回 None
速记口诀
python
容器七类分有序无序,Vec 动态数组最常用;
哈希无序树有序,队列双端 VecDeque;
迭代核心 next 返回 Option,惰性适配器不运算;
iter 借、iter_mut 改、into_iter 拿走所有权;
map 转换 filter 过滤,fold 聚合 collect 收集;
range 区间轻量迭代,链式写法替代多层循环。