web-dev-qa-db-fra.com

Que signifie «ne peut pas sortir du contenu indexé»?

Je joue avec Rust , et j'essaie d'accéder au premier argument de ligne de commande avec ce code:

use std::env;

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

Et je reçois cette erreur:

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`

Si je le change en let ref dir, ça compile, mais je ne vois pas ce qui se passe. Quelqu'un pourrait-il expliquer ce que signifie "contenu indexé"?

54
Rory

Lorsque vous utilisez un opérateur d'index ([]), Vous obtenez l'objet réel à l'emplacement d'index. Vous n'obtenez pas de référence, de pointeur ou de copie. Puisque vous essayez de lier cet objet avec une liaison let, Rust essaie immédiatement de se déplacer (ou de copier, si le trait Copy est implémenté).

Dans votre exemple, env::args() est un itérateur de Strings qui est ensuite collecté dans un Vec<String>. Il s'agit d'un vecteur appartenant à des chaînes possédées, et les chaînes possédées ne sont pas automatiquement copiables.

Vous pouvez utiliser une liaison let ref, Mais l'alternative la plus idiomatique consiste à prendre une référence à l'objet indexé (notez le symbole &):

use std::env;

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

Le déplacement implicite d'un Vec n'est pas autorisé car il le laisserait dans un état invalide - un élément est déplacé, les autres ne le sont pas. Si vous avez un Vec modifiable, vous pouvez utiliser une méthode comme Vec::remove pour supprimer une seule valeur:

use std::env;

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

Pour votre problème particulier, vous pouvez également utiliser simplement Iterator::nth :

use std::env;

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