You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中为含Future的Measurable结构体实现Future trait遇阻

解决Measurable的Future实现问题

核心问题分析

你遇到的两个问题本质上是对Future trait实现规则和Pin用法的不熟悉:

  1. 移动错误:直接将self.inner_future移入Poll::Ready会触发所有权转移,而Fut没有Copy约束,导致编译失败。
  2. 返回值困惑:Measurable作为包装器,其Future的Output必须与内部Fut的Output一致,就绪时返回内部Future的结果即可,同时附加计时逻辑。

正确实现代码

use std::future::Future;
use std::task::{Context, Poll};
use std::time::Instant;

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

impl<Fut: Future> Future for Measurable<Fut> {
    // 与内部Future的输出类型保持一致
    type Output = Fut::Output;

    fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        // 从Pin<&mut Self>中获取内部Future的Pin<&mut Fut>(无需Unpin约束)
        let this = self.get_mut();
        let inner_pin = std::pin::Pin::new(&mut this.inner_future);
        
        match inner_pin.poll(cx) {
            Poll::Ready(output) => {
                // 计算并打印纳秒级执行时长
                let elapsed_nanos = this.started_at.elapsed().as_nanos();
                println!("Future执行时长:{}纳秒", elapsed_nanos);
                // 返回内部Future的结果
                Poll::Ready(output)
            }
            Poll::Pending => Poll::Pending,
        }
    }
}

// 辅助构造函数(可选,方便创建Measurable实例)
impl<Fut: Future> Measurable<Fut> {
    fn new(inner_future: Fut) -> Self {
        Self {
            inner_future,
            started_at: Instant::now(),
        }
    }
}

关键细节说明

  • Pin的使用:因为不能依赖Fut: Unpin,我们通过self.get_mut()获取&mut Self,再用Pin::new(&mut this.inner_future)创建内部Future的Pin引用。这种方式不需要Fut实现Unpin,因为Pin<&mut T>对所有T都有效(只要不尝试获取T的所有权或非固定引用)。
  • 返回值逻辑:Measurable的职责是透明包装内部Future,所以它的Output必须和内部Future一致。当内部Future就绪时,我们先计算并打印时长,再原封不动返回内部结果;如果内部Future仍未就绪,直接返回Poll::Pending即可。
  • 计时时机:started_at在Measurable实例创建时初始化(通过new方法),确保计时从Future开始被包装时算起。

内容的提问来源于stack exchange,提问作者vsezanatodazheeto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:18:36