我遇到了一个问题,涉及到具有 Box 字段并且实现了 async 特性的结构体。具体来说:
error: future cannot be sent between threads safely
看起来错误是因为我在实现异步trait的结构体中使用了一个Box字段。
下面是我试图完成并遇到问题的最小示例。你可以在这里找到一个演示。
use async_trait::async_trait;
// My traits
#[async_trait]
pub trait InnerTrait {
async fn inner_fn(&self) -> Result<(), ()>;
}
#[async_trait]
pub trait OuterTrait {
async fn outer_fn(&self) -> Result<(), ()>;
}
// My structs
pub struct InnerStruct {}
impl InnerStruct {
pub fn new() -> impl InnerTrait {
InnerStruct {}
}
}
pub struct OuterStruct {
inner_trait: Box<dyn InnerTrait>,
}
impl OuterStruct {
pub fn new(inner_trait: Box<dyn InnerTrait>) -> impl OuterTrait {
OuterStruct { inner_trait }
}
}
// My trait impls
#[async_trait]
impl InnerTrait for InnerStruct {
async fn inner_fn(&self) -> Result<(), ()> {
println!("InnerStruct.inner_fn");
Ok(())
}
}
#[async_trait]
impl OuterTrait for OuterStruct {
async fn outer_fn(&self) -> Result<(), ()> {
println!("OuterStruct.outer_fn");
self.inner_trait.inner_fn().await;
Ok(())
}
}
#[tokio::main]
async fn main() {
let inner_trait: Box<dyn InnerTrait> = Box::new(InnerStruct::new());
let outter_trait: Box<dyn OuterTrait> = Box::new(OuterStruct::new(inner_trait));
outter_trait.outer_fn().await;
}
首先,我该如何解决这个问题?
其次,我试图为结构体编写特质(trait),使得实现它的结构体可以轻松地与其他结构体交换,类似于我可能在Java中为对象编写接口。我意识到这可能不是我在Rust中设计组件的正确方式,但作为一个初学者,我不确定应该如何处理基于特质(trait)的设计。如果这不是惯用的Rust方法,你会如何重新设计它,以便仍然能够实现设计目标(在整个堆栈中创建和使用特质(trait),以允许轻松的impl替换)?
谢谢。
#[async_trait(?Send)]
。 - Ibraheem Ahmed