为什么在使用Tokio和实验性的异步/等待支持时,Box <dyn sink =“”>不能实现Sink特性?

时间:2018-11-14 14:26:32

标签: async-await rust rust-tokio

我在Cargo.toml中启用了Tokio并启用了异步/等待功能,并且正在使用异步/等待功能(以及2018年版的最新Rust夜间版本):

tokio = { version = "0.1.11", features = ["async-await-preview"] }

我遇到了一个我不明白的错误,此错误在以下最小示例中再现:

#![feature(await_macro, async_await, futures_api)]
use tokio::prelude::*;

pub fn main() {
    tokio::run_async(async {
        let s: Option<Box<dyn Sink<SinkItem = u8, SinkError = ()> + Send + Sync + 'static>> = None;

        if let Some(sink) = s {
            await!(sink.send_async(100));
        }
    });
}

错误是:

error[E0277]: the trait bound `for<'r> (dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 'r): futures::sink::Sink` is not satisfied
 --> src/main.rs:5:5
  |
5 |     tokio::run_async(async {
  |     ^^^^^^^^^^^^^^^^ the trait `for<'r> futures::sink::Sink` is not implemented for `dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send`
  |
  = note: required because of the requirements on the impl of `futures::sink::Sink` for `std::boxed::Box<dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send>`
  = note: required because it appears within the type `tokio_async_await::sink::send::Send<'_, std::boxed::Box<dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send>>`
  = note: required because it appears within the type `for<'r, 's, 't0, 't1> {std::option::Option<std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 'r)>>, std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 's)>, tokio_async_await::sink::send::Send<'t0, std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 't1)>>, ()}`
  = note: required because it appears within the type `[static generator@src/main.rs:5:28: 11:6 for<'r, 's, 't0, 't1> {std::option::Option<std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 'r)>>, std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 's)>, tokio_async_await::sink::send::Send<'t0, std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 't1)>>, ()}]`
  = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:5:28: 11:6 for<'r, 's, 't0, 't1> {std::option::Option<std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 'r)>>, std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 's)>, tokio_async_await::sink::send::Send<'t0, std::boxed::Box<(dyn futures::sink::Sink<SinkItem=u8, SinkError=()> + std::marker::Sync + std::marker::Send + 't1)>>, ()}]>`
  = note: required because it appears within the type `impl std::future::Future`
  = note: required by `tokio::async_await::run_async`

,如果我删除以“ await!”开头的行,它将消失。

在没有实验性异步/等待支持的情况下使用Tokio时,我的程序对Box<dyn Sink>Sink的想法感到满意,因此我不确定如何使用异步来产生错误/等待东西。

错误是什么意思?我该如何解决?

1 个答案:

答案 0 :(得分:1)

我的解决方法是将Box版本的Sink包装到一个新类型中,并在其上实现Sink特性。我认为也许Box<dyn Sink>不在今晚实施Sink,这基本上就是错误消息所隐含的含义(我猜async / await垫片会重新定义Sink,并且不要在Box

我的包装纸最终看起来像这样:

struct BoxedSink<I, E>(Box<dyn Sink<SinkItem = I, SinkError = E> + Send + Sync + 'static>);

impl<I, E> Sink for BoxedSink<I, E> {
    type SinkItem = I;
    type SinkError = E;

    fn start_send(
        &mut self,
        input: Self::SinkItem,
    ) -> Result<AsyncSink<Self::SinkItem>, Self::SinkError> {
        self.0.start_send(input)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        self.0.poll_complete()
    }
}

您必须在其中包装Box<Sinks>,以使它们再次实现Sink