Asynchronous 在异步函数参数中声明特征对象的关联类型

Asynchronous 在异步函数参数中声明特征对象的关联类型,asynchronous,rust,generic-type-argument,Asynchronous,Rust,Generic Type Argument,我想要一个异步处理可变数量(Sink,Stream)元组的函数 use futures::channel::mpsc; 使用未来:{Sink,Stream,SinkExt,StreamExt}; 异步fn-foo(v:Vec){ 用于v中的(mut tx,mut rx){ 让ux=tx.send(0); 让我们等待; } } #[tokio::main] pub async fn main()->结果{ let(tx,mut-rx)=mpsc::信道(32); foo(vec![(Box::ne

我想要一个异步处理可变数量(
Sink
Stream
)元组的函数

use futures::channel::mpsc;
使用未来:{Sink,Stream,SinkExt,StreamExt};
异步fn-foo(v:Vec){
用于v中的(mut tx,mut rx){
让ux=tx.send(0);
让我们等待;
}
}
#[tokio::main]
pub async fn main()->结果{
let(tx,mut-rx)=mpsc::信道(32);
foo(vec![(Box::new(tx),Box::new(rx)))。等待;
好(())
}
但是我得到了这个编译错误:

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 错误[E0107]:类型参数数量错误:应为1,找到0 -->src/main.rs:4:30 | 4 |异步fn foo(v:Vec){ |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^应为1个类型参数
编译器提示我以这种方式声明trait对象的关联类型。我不确定它为什么不接受它。

编译器希望您指定“类型参数”这不是错误类型,而是被发送到接收器的项的类型,如在
接收器
中。您指定
u8
作为流的类型,并且在一个和另一个之间发送值不变,因此您可能需要
接收器

一旦您这样做,编译器接下来会抱怨您需要指定
Error
关联类型(这次是真实的)。但是,如果您指定
std::io::Error
,则从
main()调用
foo()
不会编译,因为
mpsc::Sender
Sink
实现将自己的
mpsc::senderro
指定为错误类型

最后,接收器和流都需要固定,以便它们可以跨越等待点。这是通过使用
Pin
而不是
Box
Box::Pin(…)
而不是
Box::new(…)
实现的

通过上述更改,编译的版本如下所示:

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(())
}
use futures::channel::mpsc;
使用未来:{Sink、SinkExt、Stream、StreamExt};
使用std::pin::pin;
异步fn-foo(
v:Vec,
) {
用于v中的(mut tx,mut rx){
让ux=tx.send(0);
让我们等待;
}
}
#[tokio::main]
pub async fn main()->结果{
let(tx,rx)=mpsc::信道(32);
foo(vec![(Box::pin(tx),Box::pin(rx)))。等待;
好(())
}

这似乎需要
foo()
只接受(
Sink
Stream
)元组的向量,而不是我的程序需要的更一般的情况。我想传递各种(tx,rx)mpsc对和其他I/O流的向量(它们都实现Sink或Stream的公共属性),这就是我使用trait对象的原因。我的参数
v
的作用类似于铁锈手册()的trait objects一章中的
components
。我怀疑铁锈可以在函数范围内处理这种情况,但在将其作为参数使用时会中断?@armani Your
foo()
使用
tx.send(0)
,所以它似乎需要数字。Rust可以处理在流中发送异构对象的问题,但您需要更精确地处理需求。目前,这个问题还没有真正的答案。够痛苦的了;我将从字节箱中选择
字节
类型,稍后再分析它。这让我可以解决我原来的er罗。
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(())
}