'Returning a reference to a captured mutable variable
So I have a function which looks like this
fn foo() {
let items = vec![0.2, 1.5, 0.22, 0.8, 0.7, 2.1];
let mut groups: HashMap<u32, String> = HashMap::new();
let mut group = |idx: f32| -> &mut String {
let rounded = (idx / 0.2).floor() as u32;
groups
.entry(rounded)
.or_insert_with(|| format!("{}:", rounded))
};
for item in items.iter() {
group(*item).push_str(&format!(" {}", item))
}
}
and this code does not compile, with the following error:
error: captured variable cannot escape `FnMut` closure body
--> src/main.rs:9:9
|
5 | let mut groups: HashMap<u32, String> = HashMap::new();
| ---------- variable defined here
6 |
7 | let mut group = |idx: f32| -> &mut String {
| - inferred to be a `FnMut` closure
8 | let rounded = (idx / 0.2).floor() as u32;
9 | groups
| ^-----
| |
| _________variable captured here
| |
10 | | .entry(rounded)
11 | | .or_insert_with(|| format!("{}:", rounded))
| |_______________________________________________________^ 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
Edit
As @Sven Marnach pointed out, the problem here is that I could create 2 mutable references to the same object:
fn foo() {
// ...
let ok = groups(0.1);
let problem = groups(0.1);
}
Original (incorrect)
I think that Rust is telling me, the closure
groupis mutably capturing the variablegroupsand then returning a reference to an object owned bygroups. So the danger here is that the following code would return a dangling pointer (sincegroupsis dropped when it goes out of scope afterfoofinishes).fn foo() -> &String { /* ... */ return groups(0.1); }
So is there any way to return a reference from a captured mutable HashMap like this?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
