我正在尝试实现一个过滤器函数,该函数接收向量的迭代器,并返回带有过滤器的迭代者。有没有什么方法可以不将迭代器的生存期链接到结构?我可以通过使迭代器的生存期取决于结构来实现它,但这不是我想要做的
这里有一个简化的代码:
struct Structure {
low: i32,
}
impl Structure {
pub fn find_low<'a>(
&mut self,
packets: impl Iterator<Item = &'a i32>,
) -> impl Iterator<Item = &'a i32> {
packets.filter(|packet| **packet < self.low)
}
pub fn new() -> Self {
Structure { low: 10 }
}
}
fn main() {
let strct = Structure::new();
let vec = [1, 2, 3, 11, 12, 13];
let mut it = strct.find_low(vec.iter());
assert_eq!(it.next().unwrap(), &vec[0]);
}
这样做,我得到一个错误
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> src/main.rs:9:10
|
7 | &mut self,
| --------- hidden type `Filter<impl Iterator<Item = &'a i32>, [closure@src/main.rs:10:24: 10:52]>` captures the anonymous lifetime defined here
8 | packets: impl Iterator<Item = &'a i32>,
9 | ) -> impl Iterator<Item = &'a i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound
|
9 | ) -> impl Iterator<Item = &'a i32> + '_ {
| ++++
游乐场
是的,有一种方法可以不将返回迭代器的生存期与引用self
的生存期联系起来:您需要将筛选闭包所需的数据移动到闭包中,这样它就不会引用它。要实现这一点,请将self.low
复制到一个局部变量中,并将其移动到闭包。
一旦你解决了这个问题,你就会发现第二个问题:你的main()
在编写时不能调用strct.find_low()
,因为strct
没有声明为mut
——但它不应该是。find_low
不必要地将self
作为可变引用,而不可变引用可以。用&self
替换&mut self
。
pub fn find_low<'a>(
&self,
packets: impl Iterator<Item = &'a i32>,
) -> impl Iterator<Item = &'a i32> {
let low = self.low;
packets.filter(move |packet| **packet < low)
}
(游乐场(
将self.low
的副本移动到闭包中的另一种选择是将&self
的生存期限制为也包括'a
,尽管这确实将返回迭代器的生存期与Structure
的生存期链接起来。
pub fn find_low<'a>(
&'a self,
packets: impl Iterator<Item = &'a i32>,
) -> impl Iterator<Item = &'a i32> {
packets.filter(move |packet| **packet < self.low)
}
(游乐场(