简体   繁体   English

如何在返回新接收的值和缓存值之间的所有组合的迭代器时修复生命周期问题?

[英]How do I fix a lifetime issue when returning an iterator of all combinations between a newly received value and cached values?

I am trying to return an iterator of all combinations between a newly received value and cached values, but I got a lifetime issue. 我试图返回一个新接收的值和缓存值之间的所有组合的迭代器,但我有一个终身问题。

use std::collections::HashMap;

pub struct Status {
    // <i,Vec<u>>
    old: HashMap<usize, Vec<usize>>,
}

impl<'a> Status {
    pub fn new() -> Self {
        Status {
            old: HashMap::new(),
        }
    }

    pub fn gen(&mut self, u: usize, i: usize) -> UserPairIter<'a> {
        let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
        UserPairIter::new(entry, u)
    }
}

struct UserPairIter<'a> {
    data: &'a mut Vec<usize>,
    u: usize,
    index: usize,
}

impl<'a> UserPairIter<'a> {
    pub fn new(data: &'a mut Vec<usize>, u: usize) -> Self {
        UserPairIter { data, u, index: 0 }
    }
}

impl<'a> Iterator for UserPairIter<'a> {
    type Item = (usize, usize);

    fn next(&mut self) -> Option<Self::Item> {
        if self.index >= self.data.len() {
            self.data.push(self.u);
            return None;
        }
        let result = (self.u, self.data[self.index]);
        self.index += 1;
        Some(result)
    }
}

fn main() {}

When I compile, I get the following error message: 当我编译时,我收到以下错误消息:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:16:50
   |
16 |         let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
   |                                                  ^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 15:5...
  --> src/main.rs:15:5
   |
15 | /     pub fn gen(&mut self, u: usize, i: usize) -> UserPairIter<'a> {
16 | |         let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
17 | |         UserPairIter::new(entry, u)
18 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:16:41
   |
16 |         let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
   |                                         ^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 8:1...
  --> src/main.rs:8:1
   |
8  | / impl<'a> Status {
9  | |     pub fn new() -> Self {
10 | |         Status {
11 | |             old: HashMap::new(),
...  |
18 | |     }
19 | | }
   | |_^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:16:41
   |
16 |         let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

First of all, do not put the lifetime generic in Status . 首先,不要将生命周期通用于Status If you need genericity in a function, put this parameter in function: 如果您需要函数的通用性,请将此参数放在函数中:

impl Status {
    pub fn new() -> Self {
        Status {
            old: HashMap::new(),
        }
    }

    pub fn gen<'a>(&mut self, u: usize, i: usize) -> UserPairIter<'a> {
        let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
        UserPairIter::new(entry, u)
    }
}

Then the compiler says that it cannot infer a lifetime for self.old . 然后编译器说它无法推断self.old的生命周期。 Just give it the hint with &'a mut self so that the compiler understands that the lifetime of the UserPairIter is the same as the lifetime of Status : 只需给它一个提示&'a mut self以便编译器理解UserPairIter的生命周期与Status的生命周期相同:

impl Status {
    pub fn new() -> Self {
        Status {
            old: HashMap::new(),
        }
    }

    pub fn gen<'a>(&'a mut self, u: usize, i: usize) -> UserPairIter<'a> {
        let entry: &'a mut Vec<usize> = self.old.entry(i).or_insert(Vec::new());
        UserPairIter::new(entry, u)
    }
}

And that is ok! 那没关系!

You do not need to say the type of entry , the compiler can infer it with the function signature: 您不需要说出entry的类型,编译器可以使用函数签名来推断它:

pub fn gen<'a>(&'a mut self, u: usize, i: usize) -> UserPairIter<'a> {
    let entry = self.old.entry(i).or_insert(Vec::new());
    UserPairIter::new(entry, u)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM