我试图在我自己的struct上实现迭代器。我的一般方法是在第一次调用next
时生成并存储迭代器,然后在每次需要值时调用此迭代器。
我的最小失败示例looks like this,其核心是:
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 = _>>);
}
我的代码无法编译,产生以下消息:
help: consider using an explicit lifetime parameter as shown: fn next(self: &'a mut Self) -> Option<<Self>::Item>
遵循建议没有帮助(只是导致更多编译错误,说我的实现与Iterator特征定义不兼容。
我很感激帮助了解出了什么问题以及如何解决问题。
答案 0 :(得分:3)
问题在于您传递给filter
的关闭需要借用self
,但you can't store a reference to self
in the struct itself。
在这种情况下,我们可以通过在闭包中存储值的副本来解决它。这分两步完成:
self.look_for
分配给局部变量,并在闭包中使用局部变量。这样,闭包不会绑定到self
。move
添加到闭包中。因此,闭包将按值捕获局部变量。这是最终的代码:
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
}
}
}
Box
上的显式强制转换不是必需的,因此我将其删除了。