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:
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
. 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.