迭代器
好的,我们来详细解释一下 Rust 中的 into_iter(), iter(), 和 iter_mut() 这三个方法。它们都是用于从集合(如 Vec, HashMap, String, 数组等)创建迭代器的核心方法,但它们在处理集合 所有权 和 元素访问权限 上有本质区别。
核心区别总结:
| 方法 | 所有权转移 | 元素访问方式 | 返回的迭代器类型 | 集合之后是否可用 |
|---|---|---|---|---|
into_iter() |
消耗 集合 (Move) | 拥有 元素 (T) |
IntoIterator::Item = T |
不可用 |
iter() |
借用 集合 (Immutable Borrow) | 不可变引用 (&T) |
Iterator::Item = &T |
可用 |
iter_mut() |
可变借用 集合 (Mutable Borrow) | 可变引用 (&mut T) |
Iterator::Item = &mut T |
可用 |
详细解释:
-
into_iter()(Into Iterator)- 所有权: 这个方法 消耗 (consume)集合本身。调用
into_iter()后, 原始集合的所有权被转移 到迭代器中。这意味着你不能再使用原来的集合变量(除非它实现了Copytrait,但集合类型通常不会)。 - 元素访问: 迭代器 产出集合中每个元素本身 (
T)。你获得了元素的所有权。 - 用途:
- 当你 不再需要原始集合 ,并且想逐个 拥有 集合中的元素进行处理时。
- 在
for循环中直接使用集合变量时,Rust 会 隐式调用into_iter()。例如:
1
2
3
4
5let v = vec![1, 2, 3];
for num in v { // 等价于 `for num in v.into_iter()`
println!("{}", num);
}
// println!("{:?}", v); // 错误!v 的所有权已被移动- 需要将集合 转换 成另一种类型时(例如
Vec<T>转换成Vec<U>)。
- 返回值: 一个迭代器,其
Item类型是T(元素类型本身)。
- 所有权: 这个方法 消耗 (consume)集合本身。调用
-
iter()(Iterator)- 所有权: 这个方法对集合进行 不可变借用 。调用
iter()后,你仍然可以继续使用原始集合。 - 元素访问: 迭代器 产出集合中每个元素的不可变引用 (
&T)。你可以读取元素的值,但不能修改它们。 - 用途:
- 当你只需要 读取 集合中的所有元素,而不需要修改它们或集合本身时。
- 需要多次遍历同一个集合时。
- 在
for循环中显式使用iter()来避免移动所有权:1
2
3
4
5let v = vec![1, 2, 3];
for num in v.iter() { // num 是 &i32
println!("{}", num);
}
println!("{:?}", v); // 正确,v 仍然可用
- 返回值: 一个迭代器,其
Item类型是&T(元素的不可变引用)。
- 所有权: 这个方法对集合进行 不可变借用 。调用
-
iter_mut()(Mutable Iterator)- 所有权: 这个方法对集合进行 可变借用 。调用
iter_mut()后,在迭代器存活期间,你 不能 再通过原始变量或其他方式 可变地访问 这个集合(Rust 的借用规则确保只有一个可变引用存在)。但是,你仍然可以在迭代完成后使用集合。 - 元素访问: 迭代器 产出集合中每个元素的可变引用 (
&mut T)。你可以 读取并修改 元素的值。 - 用途:
- 当你需要 修改 集合中的元素时。
- 例如:
1
2
3
4
5let mut v = vec![1, 2, 3];
for num in v.iter_mut() { // num 是 &mut i32
*num *= 2; // 解引用并修改值
}
println!("{:?}", v); // 输出: [2, 4, 6]
- 返回值: 一个迭代器,其
Item类型是&mut T(元素的可变引用)。
- 所有权: 这个方法对集合进行 可变借用 。调用
关键点记忆:
-
into_iter(): “我全都要!” - 拿走整个集合和里面所有东西的所有权。原集合消失。 -
iter(): “借我看看!” - 只读借用集合和里面的东西。原集合完好无损,可以继续用。 -
iter_mut(): “借我改改!” - 可修改借用集合里的东西。原集合结构还在,但里面的内容可能变了。
选择哪个?
- 想 修改元素 ?用
iter_mut()。 - 只想 读取元素 且 保留集合 ?用
iter()。 - 想 消费集合 (比如转换元素类型、把集合所有权传给其他函数)?用
into_iter()(或直接在for循环里用集合变量)。
注意:该文章由 DeepSeek R1 结合课程笔记优化生成,并由 Garusuta 修改发布