看一篇英文文章介绍了一种利用扩展Trait技巧来debug Futrue每次poll时的情况。
原文:Inspecting Futures(原文代码用的future库演示的,可能是当时异步没稳定时,下面换成了标准库)
你有没有想过你的futures在什么时候被poll,然后返回什么?这是一个future的包装类型在任何情况下都会打印出来poll的情况。
(显然,内部类型必须是Debug)。
use std::fmt::Debug;
use std::future::Future;
use std::task::{Context, Poll};
#[derive(Debug)]
pub struct InspectFuture<T, F: Future<Output=T>>
where T: Debug {
future: F,
label: String,
}
impl<T, F> Future for InspectFuture<T, F>
where T: Debug,
F: Future<Output=T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let poll = self.future.poll();
println!("Future {} polled: {:?}", self.label, poll);
poll
}
}
pub trait InspectExt<T>
where T: Debug,
Self: Future<Output=T> + Sized {
fn inspect(self, label: &str) -> InspectFuture<T, Self>;
}
impl<T, F> InspectExt<T> for F
where T: Debug,
F: Future<Output=T> {
fn inspect(self, label: &str) -> InspectFuture<T, Self> {
InspectFuture { label: label.to_owned(), future: self }
}
}
fn main() {
let result = async { 5 };
let result = result.inspect("test");//转换InspectFuture包装类,
// block_on 拉取result时,每次都会打印出进度,达到debug的目标
}
上面的思路技巧也可以用到其它地方。