Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 在'BoxStream'上使用流组合器_Rust_Future - Fatal编程技术网

Rust 在'BoxStream'上使用流组合器

Rust 在'BoxStream'上使用流组合器,rust,future,Rust,Future,在使用该库时,我遇到了这样一种情况:一个流在返回给用户之前需要通过不确定数量的其他流进行映射。由于在这个操作结束时输出流的确切类型是未知的,所以在将流存储在结构中和返回它时,我一直在使用trait对象 尽管这种方法工作得很好,但它有一个不幸的副作用,即导致内部流对象大小不定。这是一个问题,因为每个人的签名都需要Self:Sized,这意味着我甚至不能对返回的BoxStream等待(),以便将其转换为阻塞迭代器 下面是一个可能导致此问题的情况示例: struct Server { rece

在使用该库时,我遇到了这样一种情况:一个流在返回给用户之前需要通过不确定数量的其他流进行映射。由于在这个操作结束时输出流的确切类型是未知的,所以在将流存储在结构中和返回它时,我一直在使用trait对象

尽管这种方法工作得很好,但它有一个不幸的副作用,即导致内部
对象大小不定。这是一个问题,因为每个人的签名都需要
Self:Sized
,这意味着我甚至不能对返回的
BoxStream
等待(),以便将其转换为阻塞迭代器

下面是一个可能导致此问题的情况示例:

struct Server {
    receiver: Option<Box<Stream<Item = usize, Error = ()> + Send>>,
}

impl Server {
    pub fn new() -> Server {
        let (tx, rx) = channel(0);
        // do things with the tx (subscribe to tcp socket, connect to database, etc.)
        Server { receiver: Some(rx.boxed()) }
    }

    /// Maps the inner `Receiver` through another stream, essentially duplicating it.
    pub fn get_stream(&mut self) -> Result<Box<Stream<Item = usize, Error = ()> + Send>, ()> {
        let (tx, rx) = channel(0);

        let strm = self.receiver.take().unwrap();
        let mut tx_opt = Some(tx);
        let new_strm = strm.map(move |msg| {
            // unfortunate workaround needed since `send()` takes `self`
            let mut tx = tx_opt.take().unwrap();
            tx = tx.send(msg.clone()).wait().unwrap();
            tx_opt = Some(tx);
            msg
        });
        simbroker.receiver = Some(new_strm.boxed());

        Ok(rx.boxed())
    }
}

pub fn main() {
    let server = Server::new();

    // possible that this may happen 0..n times
    let rx: BoxStream<usize, ()> = server.get_stream();

    // can't do this since the inner `Stream` trait object isn't `Sized` and `wait()`
    // (along with all other stream combinators) requires that in their signatures.
    for msg in rx.wait() {
        // compiler error here
        // ...
    }
}
struct服务器{
接收人:选择权,
}
impl服务器{
pub fn new()->Server{
let(tx,rx)=信道(0);
//使用tx执行操作(订阅tcp套接字、连接到数据库等)
服务器{receiver:Some(rx.boxed())}
}
///通过另一个流映射内部“Receiver”,实质上是复制它。
pub fn get_stream(&mut self)->结果{
let(tx,rx)=信道(0);
设strm=self.receiver.take().unwrap();
让mut tx_opt=Some(tx);
让new|strm=strm.map(move | msg |{
//由于'send()'需要'self,因此需要一种不幸的解决方法`
让mut tx=tx_opt.take().unwrap();
tx=tx.send(msg.clone()).wait().unwrap();
tx_opt=一些(tx);
味精
});
simbroker.receiver=Some(new_strm.boxed());
Ok(rx.boxed())
}
}
pub fn main(){
让server=server::new();
//可能发生0..n次
让rx:BoxStream=server.get_stream();
//无法执行此操作,因为内部'Stream'trait对象不是'size'和'wait()`
//(以及所有其他流组合器)要求在其签名中使用。
对于rx.wait()中的msg{
//这里有编译器错误
// ...
}
}
如上面的代码所示,
BoxStream
s是必需的,因为在流上调用
map()
会将其类型从
Receiver
更改为
map
,这将使其无法存储回结构中。返回的
BoxStream
几乎不可能执行任何操作,因为它的大小是
。事实上,trait object
Stream
s唯一可用的函数是
poll()
,它应该永远不会在
任务之外调用


有没有什么方法可以避免这个问题,而不必返回包含可能发生的任何一种流的枚举?编写我自己的结构来实现
会以某种方式解决这个问题吗?

正如@FrancisGagné在评论中指出的那样,
futures rs
futures::Stream
模块中声明
impl Stream for Box
。在测试我的代码时,我未能导入
,因此该特征不在范围内

编译器没有因为缺少
wait()
函数而触发错误,因为它首先遇到了未大小的问题


通过添加
use futures::Stream到函数的开头。

我无法重现您的问题(在修复无关问题后)。在未来的rs中有
impl-Stream-for-Box
,这应该可以让它正常工作。确保你的问题包含一个错误消息和你收到的错误消息;在这个特定的测试中,我没有做
使用futures::Stream
;rustc遇到了未指定大小的错误,因为
impl
作为
wait()
存在于
Stream
模块中,因此编译在注意到
wait()
不在范围内之前就出错了。非常感谢@FrancisGagné!如果你想把它变成一个答案,我会接受它的解决;如果不是的话,我会自己做的。