Подтвердить что ты не робот

Что означает "не может выйти из индексированного контента"?

Я играю с 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`

Если я изменю его на let ref dir, он скомпилируется, но я не понимаю, что происходит. Может ли кто-нибудь объяснить, что означает "проиндексированный контент"?

4b9b3361

Ответ 1

Когда вы используете оператор индекса ([]), вы получаете фактический объект в месте индекса. Вы не получаете ссылку, указатель или копию. Поскольку вы пытаетесь связать этот объект с привязкой let, Rust немедленно пытается переместить (или скопировать, если реализован признак Copy).

В вашем примере env::args() является итератором String, который затем собирается в Vec<String>. Это находящийся в собственности вектор принадлежащих строк, а принадлежащие строки не могут автоматически копироваться. Перемещение из Vec недопустимо, так как оно оставит его в недопустимом состоянии - один элемент будет удален, остальные - нет.

Вы можете использовать привязку let ref, но более идиоматической альтернативой является обращение к индексированному объекту (обратите внимание на символ &):

use std::env;

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

Для вашей конкретной проблемы вы также можете просто использовать Iterator::nth:

use std::env;

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