首页 > 解决方案 > 在 async_trait 方法中等待后如何告诉编译器未使用值?

问题描述

在下面的示例代码中,非发送值 ,Vec<T>被移动到返回其他内容的函数中。在这一点上,我不再关心那个向量。返回的对象不存储对它的引用,它不再存在。

但是,当我.await在下一行时,我收到错误“捕获的值不是Send”。它不是,但由于它应该在vector_as_string退出时被销毁,所以当未来重新启动时它不需要跨线程发送它,因为该变量永远不会再次使用。

use async_trait::async_trait;

async fn write_value(value: Vec<u8>) {
    println!("something")
}

fn vector_as_string<T>(vec: Vec<T>) -> Vec<u8> {
    Vec::new()
}

#[async_trait]
trait Writer {
    async fn write_array<T>(&mut self, value: Vec<T>);
}

pub struct WriterImplementation {}

#[async_trait]
impl Writer for WriterImplementation {
    async fn write_array<T>(&mut self, value: Vec<T>) {
        let string = vector_as_string(value);

        write_value(string).await
    }
}

#[tokio::main]
async fn main() {
    println!("Hi");
}

依赖项:

[dependencies]
tokio = { version = "1.9.0", features = ["full"]}
async-trait = "0.1.51"

错误:

error: future cannot be sent between threads safely
  --> src/main.rs:20:55
   |
20 |       async fn write_array<T>(&mut self, value: Vec<T>) {
   |  _______________________________________________________^
21 | |         let string = vector_as_string(value);
22 | |
23 | |         write_value(string).await
24 | |     }
   | |_____^ future created by async block is not `Send`
   |
note: captured value is not `Send`
  --> src/main.rs:20:40
   |
20 |     async fn write_array<T>(&mut self, value: Vec<T>) {
   |                                        ^^^^^ has type `Vec<T>` which is not `Send`
   = note: required for the cast to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting this bound
   |
20 |     async fn write_array<T + std::marker::Send>(&mut self, value: Vec<T>) {
   |                            ^^^^^^^^^^^^^^^^^^^

按照它的建议添加允许它编译,但是如果我们没有在 await 中持有任何 ',因为它已经被移动了T: Send,为什么还T需要这样呢?SendT

标签: rustrust-tokio

解决方案


async_trait 文档

异步 fns 被转换为返回Pin<Box<dyn Future + Send + 'async>>和委托给私有异步独立函数的方法。

并非所有异步特征都需要dyn Future + Send. 为了避免在 async trait 方法上放置Send和限制,请在 trait 和 impl 块上调用 async trait 宏。Sync#[async_trait(?Send)]

适用于您的案例:

#[async_trait(?Send)]
trait Writer {
    async fn write_array<T>(&mut self, value: Vec<T>);
}

#[async_trait(?Send)]
impl Writer for WriterImplementation {
    async fn write_array<T>(&mut self, value: Vec<T>) {
        let string = vector_as_string(value);

        write_value(string).await
    }
}

推荐阅读