Reputation: 13853
I'm stuck in a similar situation to Borrow-check error with variable not living long enough in nested lambda but am unable to figure out how my situation differs:
let mut vec = vec![vec![0u8, 1u8], vec![2u8, 3u8], vec![4u8, 5u8]];
vec.iter().map(|row| {
row.iter()
.map(|d| format!("{:04b}", d))
.flat_map(|s| s.chars())
.collect::<Vec<_>>()
});
Which gives the error:
error[E0597]: `s` does not live long enough
--> src/main.rs:6:35
|
6 | .flat_map(|s| s.chars())
| - ^ `s` dropped here while still borrowed
| |
| borrow occurs here
7 | .collect::<Vec<_>>()
| - borrowed value needs to live until here
I worked around it by creating a new Vec
and appending, but I'm unclear why the first approach did not work.
let mut tmp = vec![];
vec.iter()
.map(|d| format!("{:04b}", d))
.for_each(|s| {tmp.append(&mut s.chars().collect::<Vec<_>>());});
Upvotes: 4
Views: 974
Reputation: 602145
You first map the closure |d| format!("{:04b}", d)
over your iterator, yielding String
s, which own their data, so this works perfectly find. The flat_map()
in the next step calls .chars()
on each String
. This implicitly derefrences the String
to an &str
, and creates a Chars
iterator referencing this borrow. But now we have a problem – nobody is owning the String
that we borrowed anymore.
One workaround is to store a temporary vector of String
s:
let mut vec = vec![vec![0u8, 1u8], vec![2u8, 3u8], vec![4u8, 5u8]];
vec.iter().map(|row| {
let strings: Vec<_> = row
.iter()
.map(|d| format!("{:04b}", d))
.collect();
strings
.iter()
.flat_map(|s| s.chars())
.collect::<Vec<_>>()
});
Now we have an owner for the intermediary String
s, and everything works fine again.
Upvotes: 3