"cannot move out of index of"是什么意思?



我正在玩 Rust,我正在尝试使用以下代码访问第一个命令行参数:

use std::env;
fn main() {
    let args: Vec<_> = env::args().collect();
    let dir = args[1];
}

我收到此错误:

error[E0507]: cannot move out of indexed content
 --> src/main.rs:5:15
  |
5 |     let dir = args[1];
  |         ---   ^^^^^^^ cannot move out of indexed content
  |         |
  |         hint: to prevent move, use `ref dir` or `ref mut dir`

或者在更高版本的 Rust 中:

error[E0507]: cannot move out of index of `std::vec::Vec<std::string::String>`
 --> src/main.rs:5:15
  |
5 |     let dir = args[1];
  |               ^^^^^^^
  |               |
  |               move occurs because value has type `std::string::String`, which does not implement the `Copy` trait
  |               help: consider borrowing here: `&args[1]`

如果我把它改成let ref dir,它会编译,但我不明白发生了什么。有人可以解释一下"索引内容"是什么意思吗?

当你使用索引运算符([])时,你会得到索引位置的实际对象。您不会获得参考、指针或副本。由于您尝试使用该对象与let绑定,因此 Rust 会立即尝试移动(或复制,如果实现了Copy特征)。

在您的示例中,env::args()String 的迭代器,然后将其收集到Vec<String>中。这是拥有的字符串的拥有向量,拥有的字符串不能自动复制。

可以使用 let ref 绑定,但更惯用的替代方法是引用索引对象(请注意&符号):

use std::env;
fn main() {
    let args: Vec<_> = env::args().collect();
    let ref dir = &args[1];
    //            ^
}

不允许隐式移出Vec,因为它会使其处于无效状态 — 一个元素被移出,其他元素则不被移出。如果你有一个可变的Vec,你可以使用像Vec::remove这样的方法来取出单个值:

use std::env;
fn main() {
    let mut args: Vec<_> = env::args().collect();
    let dir = args.remove(1);
}

另请参阅:

  • 索引操作的返回类型是什么?

对于您的特定问题,您也可以只使用Iterator::nth

use std::env;
fn main() {
    let dir = env::args().nth(1).expect("Missing argument");
}

接受的答案已经给出了解决方案。我想在语义层面上解释这个问题作为补充。

规则是:借来的价值不能移出。看到这个: E0507

[]运算符来自 Index 特征,其函数签名为:

fn index(&self, index: I) -> &<Vec<T, A> as Index<I>>::Output

如您所见,它返回一个引用,而不是拥有值。将其移出会破坏上述规则。

相关内容

最新更新