简体   繁体   English

在异步 Function 参数中声明相关的特征类型 Object

[英]Declaring Associated Type of Trait Object in Async Function Parameter

I'd like a function which asynchronously processes a variable amount of ( Sink , Stream ) tuples.我想要一个 function 异步处理可变数量的( SinkStream )元组。

use futures::channel::mpsc;
use futures::{Sink, Stream, SinkExt, StreamExt};

async fn foo(v: Vec<(Box<dyn Sink<Error = std::io::Error>>, Box<dyn Stream<Item = u8>>)>) {
    for (mut tx, mut rx) in v {
        let _ = tx.send(0);
        let _ = rx.next().await;
    }
}

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (tx, mut rx) = mpsc::channel(32);
    foo(vec![(Box::new(tx), Box::new(rx))]).await;
    
    Ok(())
}

But I get this compilation error:但我得到这个编译错误:

error[E0107]: wrong number of type arguments: expected 1, found 0
 --> src/main.rs:4:30
  |
4 | async fn foo(v: Vec<(Box<dyn Sink<Error = std::io::Error>>, Box<dyn Stream<Item = u8>>)>) {
  |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 type argument

I was prompted to declare the associated type for the trait object that way by the compiler itself.编译器本身提示我以这种方式声明特征 object 的关联类型。 I'm unsure why it does not accept it.我不确定它为什么不接受它。

The compiler wants you to specify the "type argument" of the Sink .编译器希望您指定Sink的“类型参数”。 This is not the error type, but the type of the item being sent down the sink, as in Sink<Foo> .这不是错误类型,而是发送到接收器的项目的类型,如Sink<Foo> You specify u8 as the type of the stream, and are sending the value unchanged between one and the other, so you probably want a Sink<u8> .您将u8指定为 stream 的类型,并且在一个和另一个之间发送不变的值,因此您可能需要一个Sink<u8>

Once you do that, the compiler will next complain that you need to specify the Error associated type (this time for real).一旦你这样做了,编译器接下来会抱怨你需要指定Error关联类型(这次是真实的)。 However if you specify std::io::Error , the call to foo() from main() won't compile because the implementation of Sink for mpsc::Sender specifies its own mpsc::SendError as the error type.但是,如果您指定std::io::Error ,则从main()foo()的调用将无法编译,因为mpsc::SenderSink实现将其自己的mpsc::SendError指定为错误类型。

Finally, both the sink and the stream need to be pinned so they can live across await points.最后,接收器和 stream 都需要固定,以便它们可以跨越等待点。 This is done by using Pin<Box<...>> instead of Box<...> and Box::pin(...) instead of Box::new(...) .这是通过使用Pin<Box<...>>而不是Box<...>Box::pin(...)而不是Box::new(...)来完成的。

With the above changes, a version that compiles looks like this:通过上述更改,编译后的版本如下所示:

use futures::channel::mpsc;
use futures::{Sink, SinkExt, Stream, StreamExt};
use std::pin::Pin;

async fn foo(
    v: Vec<(
        Pin<Box<dyn Sink<u8, Error = mpsc::SendError>>>,
        Pin<Box<dyn Stream<Item = u8>>>,
    )>,
) {
    for (mut tx, mut rx) in v {
        let _ = tx.send(0);
        let _ = rx.next().await;
    }
}

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (tx, rx) = mpsc::channel(32);
    foo(vec![(Box::pin(tx), Box::pin(rx))]).await;

    Ok(())
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM