在 Rust 中使用 Future 来实现结构体的 Future

问题描述 投票:0回答:1

我正在 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 创建一个包装器并打印其执行时间。然而,目前还不清楚 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. 发生移动是因为值的类型为

    Fut
    ,它没有实现
    Copy
    特征

    res = Poll::Ready(self.inner_future);

  2. 我不知道任务准备好后应该返回什么

问题是,对于这种情况我该如何正确实现 poll,我应该返回什么?也许我误解了任务。

asynchronous rust rust-futures
1个回答
0
投票

要安全地创建

Pin<&mut Field>
,您可以使用
pin-project
pin-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,
        }
    }
}

您也可以使用不安全的代码来做到这一点,但我不建议这样做。

© www.soinside.com 2019 - 2024. All rights reserved.