You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中两种Vector遍历方式的区别及相关报错疑问

Rust Vector两种遍历写法的区别解析

请问以下两种遍历Rust Vector的写法有什么区别?

let names = vec!["Bob", "Frank", "Ferris"];

for name in names.iter() {
    println!("Hello {}", name);
}
let names = vec!["Bob", "Frank", "Ferris"];

for name in &names {
    println!("Hello {}", name);
}

两者运行起来行为看起来完全一致,我是不是忽略了什么关键点?

我不确定这是不是另一个问题的重复——那个问题问的是直接遍历names和遍历names.iter()的区别。但如果是重复问题的话,为什么我必须在names前面加&才能避免下面这个报错?

Compiling playground v0.0.1 (/playground)
error[E0382]: borrow of moved value: `names`
  --> src/main.rs:15:17
   |
2  |     let names = vec!["Bob", "Frank", "Ferris"];
   |         ----- move occurs because `names` has type `Vec<&str>`, which does not implement the `Copy` trait
...
12 |     for name in names {
   |                 ----- `names` moved due to this implicit call to `.into_iter()`
...
15 |     for name in names.iter() {
   |                 ^^^^^^^^^^^^ value borrowed here after move
   |
note: `into_iter` takes ownership of the receiver `self`, which moves `names`
  --> /rustc/84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc/library/core/src/iter/traits/collect.rs:262:18
   = note: borrow occurs due to deref coercion to `[&str]`
help: consider iterating over a slice of the `Vec<&str>`'s content to avoid moving into the `for` loop
   |
12 |     for name in &names {
   |                 +

For more information about this error, try `rustc --explain E0382`.
error: could not compile `playground` due to previous error

本质等价的两种写法

你看到的这两种写法本质上完全等价,背后是Rust的语法糖和自动解引用机制在起作用:

  • names.iter() 是显式调用Vec的iter()方法,返回一个不可变引用迭代器,遍历过程中每个元素是&T类型(这里T是&str,所以元素是&&str,打印时会自动解引用)。
  • &names 是对Vec取不可变引用,由于&Vec<T>可以自动解引用为&[T](切片),而切片&[T]实现了IntoIterator trait,其迭代器同样产生&T类型的元素,和iter()的结果完全一致。

为什么直接遍历names会报错?

直接写for name in names时,调用的是Vec<T>自身的IntoIterator实现——这个实现会转移整个Vec的所有权,把Vec转换成一个消耗型迭代器。遍历完成后,names变量已经被移动,无法再被后续代码使用(比如报错里的names.iter()调用)。

而names.iter()和&names都是基于不可变引用的遍历,不会转移names的所有权,遍历结束后你仍然可以正常操作这个Vec变量。

总结

  • names.iter() 与 &names 是等价写法,均为不可变引用遍历,不消耗原Vec的所有权
  • 直接遍历names会消耗所有权,遍历后原变量无法复用

内容的提问来源于stack exchange,提问作者zmunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:42:43