试图编写递归流,其中每个流从他的父流轮询,当轮询准备好值时,它使自己的异步抓取器处理父响应,但我不知道如何存储由抓取器给定的当前future ,编译器抱怨生存期,直到我try 使用自由的异步函数(未绑定到 struct ).这里有不完整的示例,但它说明了编译器错误(在Stream实现中注释了两行):

struct AsyncFetcher {}

impl AsyncFetcher {
    async fn fetch(&self, request: String) -> String {
        format!("Response({request})")
    }
}

enum State {
    PendingParent,
    ToProcess(Option<String>),
    Processing(Pin<Box<dyn Future<Output = String>>>)
}

struct RecStream {
    parent: Option<Pin<Box<dyn Stream<Item = String>>>>,
    state: State,
    fetcher: AsyncFetcher,
}

impl RecStream {
    fn new(parent: Pin<Box<dyn Stream<Item = String>>>, fetcher: AsyncFetcher) -> Self {
        Self {
            parent: Some(parent),
            state: State::PendingParent,
            fetcher: fetcher,
        }
    }

    fn with_result(result: String, fetcher: AsyncFetcher) -> Self {
        Self {
            parent: None,
            state: State::ToProcess(Some(result)),
            fetcher: fetcher,
        }
    }
}

impl Stream for RecStream {
    type Item = String;

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> Poll<Option<Self::Item>> {
        let ref_mut = self.get_mut();
        let future = ref_mut.fetcher.fetch("Some str".to_string()).boxed();
        
        // let future = free_fut().boxed(); // - THIS WORKS
        ref_mut.state = State::Processing(future); // Getting error 'lifetime may not live long enough'
        
        return Poll::Pending;
    }
}

async fn free_fut() -> String {
    "Free string".to_string()
}

推荐答案

impl AsyncFetcher {
    async fn fetch(&self, request: String) -> String {
        format!("Response({request})")
    }
}

在此函数中,Rust推断返回的Future捕获&self的生存期,即使您从未实际使用过它.这使得将来的值不是'static,但您试图将其强制转换为dyn Future,这是隐式的'static(在没有显式生存期注释的情况下).

您可以通过将函数从async fn更改为fn并返回impl Future来解决此问题,返回async move块.由于块不会捕获self,因此返回的future 将是'static:

impl AsyncFetcher {
    fn fetch(&self, request: String) -> impl Future<Output = String> {
        async move { format!("Response({request})") }
    }
}

您也可以完全删除&self参数.

请注意,如果您打算在将来使用self,问题将再次浮出水面.在这种情况下,你需要你的AsyncFetcher被其他人拥有,或者拥有共享的所有权(Arc<AsyncFetcher>),而future 可以拥有自己的Arc.否则,您实际上是在try 将对值的引用存储在拥有它的同一个 struct 中,该 struct 为isn't something you can (easily) do in Rust.

Rust相关问答推荐

将此字符串转换为由空格字符分隔的空格

如何创建引用构造函数拥有的变量的对象?

如何导出 rust 色二进制文件中的符号

如何在Rust中表示仅具有特定大小的数组

通过不同的字段进行散列和排序的 struct (需要不同的EQ实现)

有没有办法避免在While循环中多次borrow `*分支`

如果包名称与bin名称相同,并且main.ars位于工作区的同一 crate 中,则无法添加对lib.ars的依赖

应为关联类型,找到类型参数

为什么不';t(&;mut-iter).take(n)取得iter的所有权?

为什么比较Option<;字符串>;具有常数Option<&;str>;需要显式类型转换吗?

Rust:为什么 &str 不使用 Into

Rust 为什么被视为borrow ?

如何在Rust中使用Serde创建一个自定义的反序列化器来处理带有内部标记的枚举

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

切片不能被 `usize` 索引?

将原始可变指针传递给 C FFI 后出现意外值

判断对象是 PyDatetime 还是 Pydate 的实例?

如何在 Rust 中编写修改 struct 的函数

如何将切片推入数组?

当特征函数依赖于为 Self 实现的通用标记特征时实现通用包装器