有没有办法不将迭代器的生命周期链接到结构体?
我正在尝试实现一个过滤器函数,该函数接收向量的迭代器并返回带有过滤器的迭代器。有什么方法可以不将迭代器的生命周期链接到结构体?我可以通过使迭代器的生命周期依赖于结构来使其工作,但这不是我打算做的。
这是一个简化的代码:
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> + '_ {
| ++++
I am trying to implement a filter function which receives an iterator to a vector and returns an iterator with the filter. Is there any way by which I don't link the lifetime of the iterator to the struct? I am able to make it work by making lifetime of iterator depend on the struct but that is not what I intend to do.
Here is a simplified code:
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]);
}
By doing so, I get an error
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> + '_ {
| ++++
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,有一种方法不将返回的迭代器的生命周期链接到对 self 的引用的生命周期:您需要将过滤闭包所需的数据移动到闭包中,以便它不会引用它。要实现此目的,请将 self.low 复制到局部变量并将其移动到闭包中。
解决此问题后,您将发现第二个问题:您编写的
main()
无法将strct.find_low()
调用为strct
未声明mut
——但不需要如此。当不可变引用就可以时,find_low
不必要地将self
作为可变引用。将&mut self
替换为&self
。(Playground)
另一种选择将 self.low 的副本移动到闭包中是为了限制其生命周期
&self
也包含'a
,尽管这确实将返回的迭代器的生命周期链接到Structure.
(游乐场)
Yes, there is a way not to link the lifetime of the returned iterator to that of the reference to
self
: you need to move the data the filtering closure needs into the closure so that it doesn't reference it. To accomplish this, copyself.low
into a local variable and move it into the closure.Once you fix this, you will uncover a second problem: your
main()
as written can't invokestrct.find_low()
asstrct
is not declaredmut
-- but it shouldn't need to be.find_low
needlessly takesself
as a mutable reference, when an immutable reference will do. Replace&mut self
with&self
.(Playground)
An alternative to moving a copy of
self.low
into the closure is to restrict the lifetime of&self
to include'a
as well, though this does link the lifetime of the returned iterator to that ofStructure
.(Playground)