I'm trying to write a vector with the index of the string and each character in the string.
In the example below, 0 J, 0 a, 0 n ... 1 J, 1i, ...
fn main() {
let names = vec!["Jane", "Jill", "Jack", "Johne"];
let name3 = names.iter().enumerate().flat_map(|(i, name)| {
let letters = name.chars();
let mut is = Vec::new();
for _k in 0..name.len() {
is.push(i);
}
is.iter().zip(letters).collect::<Vec<_>>()
});
for i in name3 {
println!("{:?}", i);
}
}
This gives me the error
error[E0597]: `is` does not live long enough
--> src/main.rs:9:9
|
9 | is.iter().zip(letters).collect::<Vec<_>>()
| ^^ borrowed value does not live long enough
10 | });
| - `is` dropped here while still borrowed
...
14 | }
| - borrowed value needs to live until here
I don't understand what is going on here. I've already collected the is
value.
Weirdly enough, if I flip letters
and is
, it works.
letters.zip(is)
Calling is.iter()
returns references to the values inside is
. Your final iterator type is attempting to return these references, except that the Vec
holding the values has already been deallocated.
The simplest fix is to switch to into_iter
, which takes ownership of the Vec
and all its values. The more efficient fix is to avoid creating a Vec
at all:
fn main() {
let names = vec!["Jane", "Jill", "Jack", "Johne"];
let name3 = names
.iter()
.enumerate()
.flat_map(|(i, name)| name.chars().map(move |c| (i, c)));
for i in name3 {
println!("{:?}", i);
}
}
if I flip
letters
andis
, it works.
Yes, zip
takes values that implement IntoIterator
. By flipping the arguments, you end up implicitly calling into_iter
on the Vec
. You'd get the same undesired behavior if you did letters.zip(&is)
.