在Rust中为带有Future的结构实现Future

8mmmxcuj  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(91)

我正在做Rust操场上的练习,我被一个结构的Future实现所困。下面是任务的样子:

//Provide a Future trait implementation, transparently polling the inner_future,
// and printing its execution time in nanoseconds once it's ready.
// Using Fut: Unpin trait bound (or similar) is not allowed.

struct Measurable<Fut> {
    inner_future: Fut,
    started_at: Instant,
}

字符串
任务似乎很明确。我们需要创建一个围绕Future的 Package 器,并打印其执行时间。然而,Fut是什么还不清楚。我假设它是一个Future,并起草了以下代码:

use futures::executor::block_on;
use std::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
    time::Duration,
    time::Instant,
};

#[derive(Debug)]
struct Measurable<Fut> {
    inner_future: Fut,
    started_at: Instant,
}

impl<Fut> Measurable<Fut> {
    fn new(inner_future: Fut) -> Self {
        MeasurableFuture {
            inner_future,
            started_at: Instant::now(),
        }
    }
}

impl<Fut: Future> Future for Measurable<Fut> {
    type Output = Fut::Output;

    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
        // move occurs because value has type `Fut`, which does not implement the `Copy` trait
        let res = Poll::Ready(self.inner_future);

        match res {
            // syntax says that 'result' is a Fut, should i return Fut or Fut::Output?
            Poll::Ready(result) => {
                println!(
                    "Completed: {:?}",
                    Instant::now().checked_duration_since(self.started_at)
                );
                result
                // Poll::Pending
            }
            Poll::Pending => Poll::Pending,
        }
    }
}

async fn hello_world() {
    std::thread::sleep(Duration::from_secs(1));
    println!("hello, world!");
}

fn main() {
    let w = Measurable::new(hello_world());
    let result = block_on(w);
    println!("{:?}", result);
}


所以有两个问题:
1.发生移动是因为value的类型为Fut,而Copy没有实现trait
res = Poll::Ready(self.inner_future);
1.我不知道当任务完成后我应该返回什么
问题是,对于这种情况,我应该如何正确地实现轮询,我应该返回什么?也许我误解了任务。

monwx1rj

monwx1rj1#

要安全地创建Pin<&mut Field>,您可以使用pin-projectpin-project-lite板条箱:

pin_project_lite::pin_project! {
    #[derive(Debug)]
    struct Measurable<Fut> {
        #[pin]
        inner_future: Fut,
        started_at: Instant,
    }
}

impl<Fut: Future> Future for Measurable<Fut> {
    type Output = Fut::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = self.project();

        let res = this.inner_future.poll(cx);

        match res {
            Poll::Ready(result) => {
                println!(
                    "Completed: {:?}",
                    Instant::now().checked_duration_since(*this.started_at)
                );
                Poll::Ready(result)
            }
            Poll::Pending => Poll::Pending,
        }
    }
}

字符串
你也可以使用不安全的代码,但我不建议这样做。

相关问题