我正在构建一个应用程序。它有一个核心构件,我称之为“大脑”,它了解所有子系统(例如 DB)。
我不想直接使用任何特定的 DB 实现,而是使用特征对象(或任何可以实现相同目的的东西)。
所以看起来就像
struct Brain {
db: Box<dyn DbTrait>,
}
但是,我也希望所有代码都是高效的,因此我使用 tokio,并且大多数内容都是异步的
trait DbTrait {
fn do_something(&self) -> impl Future<Output = Whatever>;
}
这会产生冲突,因为 Rust 无法从返回impl
类型的特征中创建特征对象,如下面的 MWE 所强调的那样:
trait ReturnsFutures {
fn futuristic(&self) -> impl Future<Output = ()>;
}
struct FutureReturner {}
impl ReturnsFutures for FutureReturner {
async fn futuristic(&self) {
println!("just fake async");
}
}
struct OtherFutureReturner {}
impl ReturnsFutures for OtherFutureReturner {
async fn futuristic(&self) {
println!("also fakin' it");
}
}
struct FuturisticService {
future_returner: Box<dyn ReturnsFutures>,
}
给出错误
the trait `ReturnsFutures` cannot be made into an object
consider moving `futuristic` to another trait
the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `ReturnsFutures` for this new enum and using it instead:
FutureReturner
OtherFutureReturnerrustcClick for full compiler diagnostic
目前,我能想到一种解决方法,即改为异步,特征可以返回一个通道来等待结果。虽然我觉得更复杂,但这可能是相当可行的。对于这类问题,还有其他更可行/惯用的解决方案吗?