pub trait GenericAsyncRunner{
fn return_run_function(&self) -> ?;
}
pub enum AsyncRunError{}
pub struct SpecificAsyncRunner{}
impl SpecificAsyncRunner{
async fn run(&self) -> Result<u32, AsyncRunError> {
todo!()
}
}
impl GenericAsyncRunner for SpecificAsyncRunner {
fn return_run_function(&self) -> ? {
todo!()
}
}
我想在运行时获取指向异步run
函数的指针。在实践中,我会有let generic_async_runner = Box<dyn GenericAsyncRunner>
,我想要generic_async_runner.return_run_function().await
.我可以向下抛弃,但实际上会有很多不同的SomethingAsyncRunner
所以向下抛弃必须尝试向下抛弃所有这些。
我可以将async fn run() -> Result<u32, AsyncRunError>
重写为返回Future
的脱糖版本吗?通过这种方式,我可以在上面的代码上放置一个具体的类型来?
。
async
函数还不能在特征中指定,你的例子是其中一个重要原因。您最好的选择是 归还Box<dyn Future<Output=T>>
,或使用为您执行此操作的async-trait
板条箱。
问题在于,对于可在 trait 对象上调用的方法,该方法需要为其每个实现返回完全相同的类型,以便调用方知道如何使用返回的对象,例如为其分配多少字节。
从async
函数返回的期货虽然是独一无二的,而且非常不透明。它们与函数的编译方式密切相关。async fn foo()
返回的未来可能与async fn bar()
返回的未来截然不同,这取决于他们的功能机构;例如,一个可能需要比另一个保持更多的状态。
装箱期货是解决这个问题的主要方法。通过这样做,访问和执行未来所需的信息是可用的,并在运行时查找,因此不同的 trait 实现可以在不破坏事物的情况下返回不同的未来。由于分配开销,它不是很好,但它是复杂问题的过得去的解决方案。