在 Rust 中共享对 Send 资源的不可变引用

Sharing an immutable reference to a Send resource in Rust

我正在尝试让一些异步 Rust 运行,以允许对数据库的并发访问。我知道期货需要为等待它时可以保存的所有变量实现 'Send',但我专门为数据库本身导入 Send,并在输入类型上声明它。

#[async_trait]
pub trait Database: Send {
    async fn get_something(&self) -> Option<Vec<f32>>;
}

async fn calculate_something(&mut self, db: Arc<(dyn Database + Send)>, var: i16) -> Option<f32> {
    let something = db.get_something(var).await;
    // Do stuff with the something.

    Some()
}

这给了我错误:

^ future created by async block is not `Send`
help: the trait `Sync` is not implemented for `dyn database::Database + Send`
note: captured value is not `Send`
  --> src/alarms/something_calculator.rs:31:47
   |
31 |     async fn calculate_something(&mut self, db: Arc<(dyn Database + Send)>,     var: i16) -> Option<f32> {
   |                                               ^^ has type `Arc<dyn database::Database + Send>` which is not `Send`
   = note: required for the cast to the object type `dyn Future<Output = Option<f32>> + Send`

我是 Rust 的新手,所以我确定我在做一些愚蠢的事情,但是当它在其类型中被定义为 Send 时,我无法绕过它而不实现 Send。

提前致谢。

异步函数要求所有捕获的值都是 Send,这样它本身就是 Send。要使 Arc 类型为 Send,其类型参数必须为 Sync + Send。您可以编写 db: Arc<(dyn Database + Send + Sync)> 来使异步 Future 发送。

它在错误消息中提到了这一点:

help: the trait `Sync` is not implemented for `dyn database::Database + Send

如果 db 参数尚未 Sync,但您没有提供足够的上下文来确定这一点,则此更改可能会对您的代码产生进一步的影响。