我正在尝试存储这些 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
函数创建一个具有匿名生命周期的 future ,并尝试将其存储在 self
中。 .是与 无关FuturesUnordered
即使你会像 self.futures = f
一样存储你的 future 那么编译器仍然会抛出同样的错误。一种解决方案可以使用专用生命周期来告诉编译器这是安全的,但我并不真正建议这样做,因为最终它可能会导致任何其他问题,因为它会强制在特定生命周期内借用 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;
}
}
Playground如果您的 future 不借用任何东西,其他解决方案要容易得多,您可以将没有生命周期的异步函数定义为 future builder 。
impl Readable {
fn read(&mut self) -> impl Future<Output = Result<Bytes, ()>> {
//produce bytes from self
futures::future::err(())
}
}
Playground另见:
关于rust - FuturesUnordered 的终身问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66897475/