如何实现对`async fn(&mut self)`进行轮询的`Future`?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现对`async fn(&mut self)`进行轮询的`Future`?相关的知识,希望对你有一定的参考价值。

我具有以下结构

struct Test;

impl Test {
    async fn function(&mut self) {}
}

我想在std::future::Future上实现一个futures::Stream(实际上是Test,但基本相同),这会轮询function。我的第一次尝试看起来像这样

impl Future for Test {
    type Output = ();
    fn poll(self: Pin<&mut self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        match self.function() {
            Poll::Pending => Poll::Pending,
            Poll::Ready(_) => Poll::Ready(()),
        }
    }
}

显然,这没有用。我知道,必须调用一次function,返回的Future必须存储在结构中的某个位置,然后必须对保存的将来进行轮询。因此,我已经尝试过此

struct Test(Option<Box<Pin<dyn Future<Output = ()>>>);
impl Test {
    async fn function(&mut self) {}
    fn new() -> Self {
        let mut s = Self(None);
        s.0 = Some(Box::pin(s.function()));
        s
    }
}

而且,很意外,这也没有用

问题是,在我调用function()之后-我已经获得了&mutTest引用,因此我无法更改Test变量,因此-无法存储返回的[ Future中的Test

答案
[我不确定您要实现什么以及为什么实现,但是我怀疑您是基于某些古老的教程或误解并只是使事情变得过于复杂而试图实现Future for Test

您不必手动实现Futureasync功能

async fn function(...) {...}

实际上只是语法糖在后台翻译成类似的东西

fn function(...) -> Future<()> {...}

您要做的就是以与任何将来相同的方式使用函数的结果,例如在其上使用等待或调用阻塞反应堆,直到完成。例如。根据您的第一个版本,您可以简单地调用:

let mut test = Test{}; test.function().await;

以上是关于如何实现对`async fn(&mut self)`进行轮询的`Future`?的主要内容,如果未能解决你的问题,请参考以下文章

&‘a mut self is restrictive

为啥 &mut self 允许借用 struct 成员,但不允许将 self 借用到不可变方法?

Rust futures: async fn 中的 thread::sleep 和阻塞调用

swift 动画转场要在主线程

从`async fn`返回的future的具体类型是啥?

异步 callback vs promise vs async/await