Rust中为含Future的Measurable结构体实现Future trait遇阻
解决Measurable的Future实现问题
核心问题分析
你遇到的两个问题本质上是对Future trait实现规则和Pin用法的不熟悉:
- 移动错误:直接将
self.inner_future移入Poll::Ready会触发所有权转移,而Fut没有Copy约束,导致编译失败。 - 返回值困惑:
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
相关产品推荐
相关产品推荐

