简体   繁体   中英

Trying to implement an iterator: cannot infer an appropriate lifetime due to conflicting requirements

I'm trying to implement an iterator on my own struct. My general approach is by generating and storing an iterator the first time next is invoked, and then calling this iterator each time I need a value.

My minimal failing example looks like this , and the heart of it is:

    if !self.vals.is_some() {
        self.vals = Some(Box::new({
            self.display.chars().filter(|&i| i == self.look_for)
        }) as Box<std::iter::Iterator<Item = _>>);
    }

My code fails to compile, producing the following message:

help: consider using an explicit lifetime parameter as shown: fn next(self: &'a mut Self) -> Option<<Self>::Item>

Following the advice doesn't help (just leads to more compile errors saying that my implementation is incompatible with the Iterator trait definition.

I'd appreciate help understanding what's going wrong and how I can fix it.

The problem is that the closure you pass to filter needs to borrow self , but you can't store a reference to self in the struct itself .

In this case, we can work around it by storing a copy of the value in the closure instead. This is done in two steps:

  1. Assign self.look_for to a local variable, and use the local variable in the closure instead. This way, the closure is not tied to self .
  2. Add move to the closure. The closure will thus capture the local variable by value.

Here's the final code:

impl<'a> Iterator for StatefulCounter<'a> {
    type Item = bool;
    fn next(&mut self) -> Option<Self::Item> {
        if !self.vals.is_some() {
            let look_for = self.look_for;
            self.vals = Some(Box::new({
                self.display.chars().filter(move |&i| i == look_for)
            }));
        }

        if let &Some(v) = &self.vals.as_mut().unwrap().next() {
            Some(expensive(v))
        } else {
            None
        }
    }
}

The explicit cast on the Box is not necessary, so I removed it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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