使用动态类型化对象实现"tokio::io::AsyncWrite"



我对 Rust 很陌生,所以也许我错过了一些明显的东西。

此代码工作正常:

pub fn say_hello() {
let fut = tokio::io::write_all(tokio::io::stdout, "Hello, world!").then(|_| {});
tokio::run(fut);
}

而以下代码编译失败:

pub fn say_hello(w: Box<dyn tokio::io::AsyncWrite>) {
let fut = tokio::io::write_all(w, "Hello, world!").then(|_| {});
tokio::run(fut);
}

编译器错误为:

error[E0277]: `dyn tokio_io::async_write::AsyncWrite` cannot be sent between threads safely

有没有办法完成我想要的(实际上是动态调度,而不仅仅是使函数通用)。

TL;DRtokio::runexpects未来,在Send'static生命周期内实施。

如果向参数添加所需的限制,它将与Stdout相同:

pub fn say_hello(w: Box<dyn tokio::io::AsyncWrite + Send + 'static>) {
let fut = tokio::io::write_all(w, "Hello, world!").then(|_| Ok(()));
tokio::run(fut);
}

注意:Stdout工作是因为 Stdout 实现已经包含Send,并且它是封闭范围的自有数据。


但是 Rust 如何能够知道write_all创建的Future是否Send

使用AsyncWrite的实现调用write_all是可以的,因为tokio::io::write_all期望实现AsyncWrite。但是tokio::run期望一个拥有'staticFuture实现Send

您正在尝试运行WriteAll未来,但请检查此SendWriteAll实现,它仅在TA实现Send时实现Send。在您的情况下T是您的 buf 类型,它是&'static str,它实现了 Send,AAsyncWrite的实现。

在这个定义中,没有声明wSend(或者它有一个'static/拥有的生命周期):

pub fn say_hello(w: Box<dyn tokio::io::AsyncWrite>) 

这就是为什么东京跑不接受WriteAll未来。

最新更新