gpt4 book ai didi

oop - 具有 Box 字段并实现异步特征的 Rust 结构

转载 作者:行者123 更新时间:2023-12-03 11:28:29 25 4
gpt4 key购买 nike

我遇到了具有 Box 字段和 impl 异步特征的结构的问题。具体来说

error: future cannot be sent between threads safely
看起来发生错误是因为我在 impl 是异步特征的结构中使用了 Box 字段。
以下是我要完成的工作和遇到的问题的一个最小示例。你可以找到它的游乐场 here .
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;
}
首先,我该如何解决这个问题?
其次,我本质上是在尝试为结构编写特征,以便可以轻松地将 impl'ing 结构与其他结构交换出来,类似于我在 Java 中为对象编写接口(interface)的方式。我意识到这可能不是我在 Rust 中考虑组件设计的方式,但我是一个初学者,不确定什么是处理基于 trait 的设计的正确方法。如果这不是惯用的 Rust,您将如何重新设计它以使其仍能实现设计目标(在堆栈上下创建和使用特征以允许轻松的 impl 交换)?
谢谢。

最佳答案

异步 fns 由 async_trait 转换进入以下:

fn your_function<'async_trait>(
&'async_trait self,
) -> Pin<Box<dyn std::future::Future<Output = ()> + Send + 'async_trait>>
where
Self: Sync + 'async_trait,
注意 SendSync requirements,它告诉编译器 future 可以在线程之间传输和共享。如果您使用像 tokio 这样的多线程执行器,这将非常有用。 .
如果您不需要线程安全的 future ,您可以避免使用 SendSync使用 #[async_trait(?Send)] 设置在异步 trait 方法上的界限:
#[async_trait(?Send)]
pub trait InnerTrait {
async fn inner_fn(&self) -> Result<(), ()>;
}

#[async_trait(?Send)]
impl InnerTrait for InnerStruct {
async fn inner_fn(&self) -> Result<(), ()> {
println!("InnerStruct.inner_fn");
Ok(())
}
}
另一方面,如果您需要线程安全的 future ,您可以添加 SendSync将满足 async_trait 的结构的界限 future 要求:
pub struct OuterStruct {
inner_trait: Box<dyn InnerTrait + Send + Sync>,
}

关于oop - 具有 Box 字段并实现异步特征的 Rust 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65028499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com