我在 rust 迹斑斑的操场上做练习,而我却执着于实现一个 struct 的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.ner_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.ner_Future);

  2. 我不知道当任务完成后我应该返回什么

问题是,我如何正确地实现这种情况下的民意测验,以及我应该返回什么?也许我误解了这项任务.

推荐答案

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

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,
        }
    }
}

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

Rust相关问答推荐

取得本地对象字段的所有权

Rust&;Tokio:如何处理更多的信号,而不仅仅是SIGINT,即SIGQUE?

在0..1之间将U64转换为F64

这是什么:`impl Trait for T {}`?

当我try 使用 SKI 演算中的S I I实现递归时,为什么 Rust 会失败?

在 Rust 中查找向量中 dyn struct 的索引

Rust typestate 模式:实现多个状态?

bcrypt 有长度限制吗?

为什么我不能克隆可克隆构造函数的Vec?

使用 `clap` 在 Rust CLI 工具中设置布尔标志

试图理解 Rust 中的可变闭包

将一片字节复制到一个大小不匹配的数组中

Rustfmt 是否有明确类型的选项?

使用泛型作为关联类型,没有幻像数据

提取 struct 生成宏中字段出现的索引

为什么这个闭包没有比 var 长寿?

在 Rust 中获得准确时间的正确方法?

Rust:如果我知道只有一个实例,那么将可变borrow 转换为指针并返回(以安抚borrow 判断器)是否安全?

在使用大型表达式时(8k 行需要一小时编译),是否可以避免 Rust 中的二次编译时间?

如何在 Rust 中使用特征标志来捕获多行代码?