Cannot infer an appropriate lifetime when storing Peekable iterators in a vector

徘徊边缘 提交于 2019-12-04 06:23:49

问题


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 Peekables 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!