如何解决FuturesUnordered 的终身问题
我正在尝试将这些 Readable
实例存储在 Coordinator
结构中
并有一个 schedule
方法,该方法选择 readables
之一并将其推送到 FuturesUnordered 实例(也在 Coordinator
内)以供稍后拉取。
问题是:由于生命周期错误而无法编译
use bytes::Bytes;
use futures::prelude::stream::FuturesUnordered;
use std::future::Future;
use std::pin::Pin;
struct Readable {}
impl Readable {
async fn read(&mut self) -> Result<Bytes,()> {
Err(())
}
}
type Futures = FuturesUnordered<Pin<Box<dyn Future<Output = Result<Bytes,()>> + Send>>>;
struct Coordinator {
readers: Vec<Readable>,futures: Futures,}
impl Coordinator {
fn schedule(&mut self) {
let reader = self.readers.get_mut(0).unwrap();
let f = Box::pin(reader.read());
self.futures.push(f);
}
}
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/lib.rs:23:22
|
22 | fn schedule(&mut self) {
| --------- this data with an anonymous lifetime `'_`...
23 | let reader = self.readers.get_mut(0).unwrap();
| ^^^^^^^^^^^^ ...is captured here...
24 | let f = Box::pin(reader.read());
25 | self.futures.push(f);
| - ...and is required to live as long as `'static` here
error: aborting due to prevIoUs error
游乐场链接:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2b69f519de1ac60b30bbbfb4a3cc3b7d
任何人都可以帮助我理解为什么这是一个问题?
具体来说,当我尝试推入 FuturesUnordered
时似乎在抱怨,但我没有看到 push 方法有任何生命周期限制:
/// Push a future into the set.
///
/// This method adds the given future to the set. This method will not
/// call [`poll`](core::future::Future::poll) on the submitted future. The caller must
/// ensure that [`FuturesUnordered::poll_next`](Stream::poll_next) is called
/// in order to receive wake-up notifications for the given future.
pub fn push(&self,future: Fut) {...}
我认为这也可能与这个具有自引用的特定结构有关(即:Coordinator::futures
正在引用 Coordinator::readers
),但我不完全明白这是否相关。
解决方法
如果我们展开我们的异步函数,它会是这样的:
fn read<'a>(&'a mut self) -> impl Future<Output = Result<Bytes,()>> + 'a
如您所见,生命周期 'a
已在返回的 Future
类型中捕获,此 'a
是匿名生命周期,因为此 read
函数可以从任何位置调用.
这导致了我们的问题;从编译器的角度来看,您的 schedule
函数创建了一个具有匿名生命周期的未来,并尝试将其存储在 self
中。它与 FuturesUnordered
无关,即使您将未来存储为 self.futures = f
,那么编译器仍会抛出相同的错误。
一种解决方案可以使用专用生命周期来告诉编译器这是安全的,但我并不真正建议这样做,因为最终它可能会导致任何其他问题,因为它会强制在特定生命周期内借用 self,如下面的代码所示。
impl<'a> Coordinator<'a> {
fn schedule(&'a mut self) {//forced
let reader = self.readers.get_mut(0).unwrap();
let f = Box::pin(reader.read());
self.futures = f;
}
}
如果您的未来不借用任何东西,其他解决方案会容易得多,您可以将没有生命周期的异步函数定义为未来的构建器。
impl Readable {
fn read(&mut self) -> impl Future<Output = Result<Bytes,()>> {
//produce bytes from self
futures::future::err(())
}
}
另见:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。