I have this data structure.
let bucket = HashMap<&str, Vec<&str>>
Given
let cluster = Vec<&str>
I want to expand it from the Vecs on Bucket and I can guarantee that I will just access each key value pair once and the &str in cluster are always a key in bucket.
use std::collections::HashMap;
fn main() {
let mut bucket: HashMap<&str, Vec<&str>> = HashMap::new();
bucket.insert("a", vec!["hello", "good morning"]);
bucket.insert("b", vec!["bye", "ciao"]);
bucket.insert("c", vec!["good"]);
let cluster = vec!["a", "b"];
let cluster2 = vec!["c"];
let mut clusters = [cluster, cluster2];
clusters.iter_mut().for_each(|cluster| {
// I don't like this clone
let tmp = cluster.clone();
let tmp = tmp.iter().flat_map(|seq| bucket[seq].
clone() // I really don't like this other clone
);
cluster.extend(tmp);
});
println!("{:?}", clusters);
}
This compiles but what I really want to do is drain the vector on bucket since I know I won't access it again.
let tmp = tmp.iter().flat_map(|seq| bucket.get_mut(seq).
unwrap().drain(..)
);
That gives me a compiler error:
error: captured variable cannot escape `FnMut` closure body
--> src/main.rs:13:45
|
4 | let mut bucket: HashMap<&str, Vec<&str>> = HashMap::new();
| ---------- variable defined here
...
13 | let tmp = tmp.iter().flat_map(|seq| bucket.get_mut(seq).
| - ^-----
| | |
| ___________________________________________|_variable captured here
| | |
| | inferred to be a `FnMut` closure
14 | | unwrap().drain(..)
| |______________________________^ returns a reference to a captured variable which escapes the closure body
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
Do I need to go unsafe? How? And more importantly, is it reasonable to want to remove that clone?