问题
The following code works perfectly:
use std::iter::Peekable;
use std::slice::Iter;
fn has_next(iter: &mut Peekable<Iter<usize>>) -> bool {
match iter.peek() {
Some(_) => true,
None => false,
}
}
fn print_iters(iters: &mut Vec<Peekable<Iter<usize>>>) {
for iter in iters.iter_mut() {
if has_next(iter) {
match iter.next() {
Some(x) => println!("{}", x),
None => {}
}
}
}
}
fn main() {
let v1 = vec![2, 4, 6, 8];
let v2 = vec![1, 3, 5, 7];
let mut iters = Vec::new();
iters.push((v1.iter().peekable()));
iters.push((v2.iter().peekable()));
print_iters(&mut iters);
}
In some code I wrote, I need to store the Peekable
s in a vector and iterate using them at a later time. I tried modifying the code to this:
use std::iter::Peekable;
use std::slice::Iter;
fn has_next(iter: &mut Peekable<Iter<usize>>) -> bool {
match iter.peek() {
Some(_) => true,
None => false,
}
}
fn print_iters(iters: &mut Vec<Peekable<Iter<usize>>>) {
for iter in iters.iter_mut() {
if has_next(iter) {
match iter.next() {
Some(x) => println!("{}", x),
None => {}
}
}
}
}
fn init_iters(v: &Vec<Vec<usize>>, iters: &mut Vec<Peekable<Iter<usize>>>) {
for i in v.iter() {
iters.push(i.iter().peekable());
}
}
fn main() {
let v1 = vec![2, 4, 6, 8];
let v2 = vec![1, 3, 5, 7];
let v = vec![v1, v2];
let mut iters = Vec::new();
init_iters(v, &mut iters);
print_iters(&mut iters);
}
When I do this, I get the following error:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:23:20
|
23 | for i in v.iter() {
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 22:79...
--> src/main.rs:22:80
|
22 | fn init_iters(v: &Vec<Vec<usize>>, iters: &mut Vec<Peekable<Iter<usize>>>) {
| ________________________________________________________________________________^
23 | | for i in v.iter() {
24 | | iters.push(i.iter().peekable());
25 | | }
26 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:23:18
|
23 | for i in v.iter() {
| ^
note: but, the lifetime must be valid for the anonymous lifetime #3 defined on the body at 22:79...
--> src/main.rs:22:80
|
22 | fn init_iters(v: &Vec<Vec<usize>>, iters: &mut Vec<Peekable<Iter<usize>>>) {
| ________________________________________________________________________________^
23 | | for i in v.iter() {
24 | | iters.push(i.iter().peekable());
25 | | }
26 | | }
| |_____^
note: ...so that expression is assignable (expected std::iter::Peekable<std::slice::Iter<'_, _>>, found std::iter::Peekable<std::slice::Iter<'_, _>>)
--> src/main.rs:24:24
|
24 | iters.push(i.iter().peekable());
| ^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> src/main.rs:33:20
|
33 | init_iters(v, &mut iters);
| ^ expected reference, found struct `std::vec::Vec`
|
= note: expected type `&std::vec::Vec<std::vec::Vec<usize>>`
found type `std::vec::Vec<std::vec::Vec<{integer}>>`
= help: try with `&v`
Why do I get this error? How do I fix it?
回答1:
By the rules of lifetime elision your function init_iters
expands to
fn init_iters<'a, 'b, 'c>(v : &'a Vec<Vec<usize>>,
iters : &'b mut Vec<Peekable<Iter<'c, usize>>>) {
for i in v.iter() {
iters.push(i.iter().peekable());
}
}
The vector's lifetime 'a
and Iter
's lifetime 'c
are declared as independent. The compiler doesn't try to infer lifetime bounds which are not explicitly specified. The error tells you that compiler cannot prove that 'c
will not outlive 'a
because they are declared as independent.
To fix it, you need to tell the compiler that Iter
doesn't outlive the vector it refers to. Using the lifetime bound 'a: 'c
does it.
fn init_iters<'a: 'c, 'b, 'c>( ...
Playground link
来源:https://stackoverflow.com/questions/45003170/cannot-infer-an-appropriate-lifetime-when-storing-peekable-iterators-in-a-vector