Je voudrais supprimer un élément aléatoire d'un fichier HashMap
. Cependant, j'ai continué à obtenir cette erreur.
error[E0502]: cannot borrow `self.map` as mutable because it is also borrowed as immutable
--> src/main.rs:23:9
|
21 | let key_to_delete = self.map.keys().skip(x).next().unwrap();
| -------- immutable borrow occurs here
22 | println!("key_to_delete: {:?}", key_to_delete);
23 | self.map.remove(&key_to_delete);
| ^^^^^^^^^------^^^^^^^^^^^^^^^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.
Cependant, si j'ajoute un .clone()
à la fin de cette ligne, l'erreur a disparu. Bien que j'aie résolu ce problème (principalement par essais et erreurs), je ne comprends toujours pas pourquoi cela fonctionne. Plus précisément, pourquoi cette erreur apparaît-elle en premier lieu ? La référence immuable à self.map
sont abandonnés après la ligne
let key_to_delete = self.map.keys().skip(x).next().unwrap()
finir de s'exécuter ? Dans cet exemple, la clé est de type i32
qui ne prend que 4 octets. Par conséquent, il est possible de cloner. Mais que se passe-t-il si la clé est un gros struct ou un clone
n'est pas souhaitable pour d'autres raisons ? Comment alors résoudre ce problème ?
Une autre observation est que mon IDE (Intellij avec le plugin rust) a montré que le type de key_to_delete
es &i32
si je n'ai pas .clone()
y i32
si je le fais. Je ne suis pas sûr que ce soit important.
Toute clarification est appréciée.
Voici mon code.
use std::collections::HashMap;
use rand::{Rng, thread_rng};
#[derive(Debug)]
struct MyStruct {
map: HashMap<i32, i32>,
}
impl MyStruct {
fn new() -> Self {
MyStruct { map: HashMap::new() }
}
fn add(&mut self, key: i32, value: i32) {
self.map.insert(key, value);
println!("after add: {:?}", self.map);
}
fn delete(&mut self) {
let x: usize = thread_rng().gen_range(0..self.map.len());
let key_to_delete = self.map.keys().skip(x).next().unwrap().clone(); // this "clone" is critical
println!("key_to_delete: {:?}", key_to_delete);
self.map.remove(&key_to_delete);
println!("map after delete: {:?}", self.map);
}
}
fn main() {
let mut c = MyStruct::new();
c.add(1, 2);
c.add(3, 4);
c.add(5, 6);
c.delete();
}