Your problem has nothing to do with iterators at all.
To quote the error verbatim:
<anon>:17:36: 17:49 error: borrowed value does not live long enough
<anon>:17 foo.vecs.push(&mut s.into_iter());
^~~~~~~~~~~~~
<anon>:10:7: 21:2 note: reference must be valid for the block suffix following statement 1 at 10:6...
<anon>:10 };
<anon>:11
<anon>:12 let mut it = seq.iter();
<anon>:13 loop {
<anon>:14 match it.next() {
<anon>:15 None => break,
...
<anon>:17:17: 17:51 note: ...but borrowed value is only valid for the statement at 17:16
<anon>:17 foo.vecs.push(&mut s.into_iter());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:17:17: 17:51 help: consider using a `let` binding to increase its lifetime
<anon>:17 foo.vecs.push(&mut s.into_iter());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"borrowed value does not live long enough"—the thing you're trying to borrow does not continue to exist for long enough. s.into_iter()
results in a temporary value that, because you don't store it anywhere, disappears at the end of the statement. You are trying to store a pointer to this temporary value in a vector which will almost certainly outlive said value. This would be very bad.
You can't just store the temporary, though, because you need to make all the iterators outlive the vector you're storing them in. The simplest solution is to just Box
them:
struct Foo<T> {
vecs: Vec<Box<Iterator<Item=T>>>,
}
fn main() {
let seq: Vec<Vec<i32>> = vec![vec![0,1], vec![2,3]];
let mut foo = Foo {
vecs: Vec::new(),
};
let mut it = seq.into_iter();
loop {
match it.next() {
None => break,
Some(s) => {
foo.vecs.push(Box::new(s.into_iter()));
},
};
}
}
Allocating them on the heap avoids the problem entirely. That said, I also had to change seq.iter()
to seq.into_iter()
because the first was iterating over &Vec<i32>
s, which meant the subsequent s.into_iter()
was also producing borrowed iterators, which aren't hugely useful in this context. Well, not unless you change it to do this instead:
struct Foo<'a, T> {
vecs: Vec<Box<Iterator<Item=T>+'a>>,
}
fn main() {
let seq: Vec<Vec<i32>> = vec![vec![0,1], vec![2,3]];
let mut foo = Foo {
vecs: Vec::new(),
};
let mut it = (&seq).into_iter();
loop {
match it.next() {
None => break,
Some(s) => {
foo.vecs.push(Box::new(s.into_iter()));
},
};
}
}
Note the explicit lifetime for tracking how long the boxed iterators are valid.