«Use of moved value» en Rust : comment corriger sans perdre la raison

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

«Use of moved value» en Rust : pourquoi cela se produit et comment vivre avec

\n\n

Si vous venez tout juste de commencer à apprendre Rust, vous avez sûrement déjà rencontré le message mystérieux : error[E0382]: use of moved value. Le compilateur râle, vous vous grattez la tête, et un code logiquement parfait refuse de se compiler. Cela vous dit quelque chose ? Bienvenue dans le monde de la possession et de l'emprunt — les concepts clés de Rust qui le rendent sûr, mais qui laissent parfois même les développeurs expérimentés perplexes.

\n\n

Cet article n'est pas une documentation aride, mais une analyse vivante du problème. Nous examinerons pourquoi l'erreur use of moved value se produit, avec des exemples de code concrets, et surtout, que faire pour y remédier. Vous apprendrez à penser comme le borrow checker et cesserez de lutter contre lui. C'est parti !

\n\n

Qu'est-ce qu'un « move » en Rust et pourquoi le compilateur est-il si strict ?

\n\n

En Rust, chaque valeur a exactement un propriétaire (owner). Lorsque vous assignez une valeur à une autre variable ou que vous la passez à une fonction, la propriété est déplacée (move). Après le déplacement, la variable d'origine devient invalide — le compilateur interdit d'y accéder. C'est la racine de l'erreur use of moved value.

\n\n

Regardez cet exemple très simple :

\n\n
let s1 = String::from("bonjour");\nlet s2 = s1; // La propriété est déplacée de s1 à s2\nprintln!("{}", s1); // ERREUR : use of moved value: `s1`
\n\n

Pourquoi cela ? String n'est pas une simple copie sur la pile. Elle stocke des données sur le tas. Si Rust copiait simplement le pointeur, lors de la libération de la mémoire, les deux variables tenteraient de la supprimer — double free. Au lieu de cela, Rust « déplace » la propriété : désormais, s2 est responsable de la mémoire, et s1 n'existe plus du point de vue du compilateur. C'est l'idée fondamentale de la sémantique de déplacement en Rust.

\n\n

Scénarios typiques menant à l'erreur

\n\n

L'erreur use of moved value se rencontre le plus souvent dans trois situations :

\n\n
    \n
  • Passer une valeur à une fonction
  • \n
  • Assigner une valeur à une autre variable
  • \n
  • Utiliser une valeur dans une boucle ou un itérateur
  • \n
\n\n

Examinons chaque cas en détail.

\n\n

1. Passage à une fonction sans retour

\n\n
fn print_string(s: String) {\n    println!("{}", s);\n}\n\nfn main() {\n    let my_string = String::from("Rust");\n    print_string(my_string); // propriété déplacée\n    println!("{}", my_string); // erreur ! use of moved value\n}
\n\n

Après l'appel à print_string, la propriété de my_string est passée à la fonction. Lorsque la fonction se termine, s est supprimée, et my_string n'est plus valide. Le compilateur vous protège de l'utilisation d'un objet mort.

\n\n

2. Assignation sans copie

\n\n

Nous avons déjà vu cet exemple avec String. Mais il est important de noter que tous les types ne se comportent pas ainsi. Les types simples comme i32, bool, f64 implémentent le trait Copy. Ils ne sont pas déplacés, mais copiés automatiquement.

\n\n
let x = 5;\nlet y = x; // copie, pas de déplacement\nprintln!("{}", x); // fonctionne !
\n\n

Les types qui stockent des données sur le tas (String, Vec, Box) n'implémentent pas Copy — seulement Clone. Par conséquent, ils sont déplacés.

\n\n

3. Itération sur une collection

\n\n

Une autre source fréquente d'erreurs est la boucle for :

\n\n
let v = vec![1, 2, 3];\nfor x in v { // v est déplacé dans l'itérateur\n    println!("{}", x);\n}\nprintln!("{:?}", v); // erreur ! use of moved value
\n\n

Lorsque vous écrivez for x in v, vous appelez en réalité into_iter(), qui consomme le vecteur. Après la boucle, v n'existe plus.

\n\n

Comment corriger : 4 méthodes éprouvées

\n\n

Mainte

Blogs

Book Recommendations