Rust 如何合并流的迭代器?
我正在写一个程序,从使用锈迹刮去链接。我正在使用Rust 如何合并流的迭代器?,rust,Rust,我正在写一个程序,从使用锈迹刮去链接。我正在使用hyper和futures 我收集了指向每个部分的链接,并使用stream::unfold构建对每个页面的访问: // Returns the links scraped, and probably Uri to the next page. fn process_body_and_return_next(body: Body) -> (Vec<String>, Option<Uri>) { ... } // In
hyper
和futures
我收集了指向每个部分的链接,并使用stream::unfold
构建对每个页面的访问:
// Returns the links scraped, and probably Uri to the next page.
fn process_body_and_return_next(body: Body) -> (Vec<String>, Option<Uri>) { ... }
// In main()
let mut core = Core::new().unwrap();
let handle = core.handle();
let client = Client::new(&handle);
let uris = ...
let jobs = uris.map(|uri| {
stream::unfold(Some(uri), |uri| {
uri.map(|uri| {
client
.get(uri)
.and_then(|res| res.body().concat2())
.map(process_body_and_return_next)
})
})
});
但这并不高效,因为我希望异步发送多个web请求。只要内部
流
准备就绪,组合的流
就会产生值。可以使用将迭代器转换为流,这允许您的流迭代器转换为流:
::futures::stream::iter_ok(jobs)
然后,您可以使用以下方法将此流平坦化为所有项目的单个流:
可以使用将迭代器转换为流,这允许您的流迭代器转换为流:
::futures::stream::iter_ok(jobs)
然后,您可以使用以下方法将此流平坦化为所有项目的单个流:
组合器获取两个流
s,并在两个流中的一个准备就绪时生成
为了从两个以上的流中进行选择,您可以将调用链接到select
。但是,由于您事先不知道必须选择打开的流的数量,因此必须将中间流框起来,以便删除特定的流
类型,以便程序类型进行检查
extern crate futures;
use futures::Stream;
fn select_all<'a, I, T, E>(seq: I) -> Box<Stream<Item = T, Error = E> + 'a>
where
I: IntoIterator,
I::Item: Stream<Item = T, Error = E> + 'a,
T: 'a,
E: 'a,
{
let mut iter = seq.into_iter();
let mut result = Box::new(iter.next().expect("got an empty list of streams"))
as Box<Stream<Item = T, Error = E>>;
while let Some(next) = iter.next() {
result = Box::new(result.select(next));
}
result
}
extern板条箱期货;
使用流;
fn选择所有
哪里
I:迭代器,
I::Item:Stream+'a,
T:a,
E:“a,
{
让mut iter=seq.into_iter();
让mut result=Box::new(iter.next().expect(“得到一个空的流列表”))
as盒;
而让一些(下一个)=iter.next(){
结果=框::新建(结果。选择(下一步));
}
后果
}
当然,有一种更有效的方法来实现这一点。有一个未来的组合,但还没有一个流。也许您可以自己实现它,并将其作为pull请求提交 组合器获取两个流
s,并在两个流中的一个准备就绪时生成
为了从两个以上的流中进行选择,您可以将调用链接到select
。但是,由于您事先不知道必须选择打开的流的数量,因此必须将中间流框起来,以便删除特定的流
类型,以便程序类型进行检查
extern crate futures;
use futures::Stream;
fn select_all<'a, I, T, E>(seq: I) -> Box<Stream<Item = T, Error = E> + 'a>
where
I: IntoIterator,
I::Item: Stream<Item = T, Error = E> + 'a,
T: 'a,
E: 'a,
{
let mut iter = seq.into_iter();
let mut result = Box::new(iter.next().expect("got an empty list of streams"))
as Box<Stream<Item = T, Error = E>>;
while let Some(next) = iter.next() {
result = Box::new(result.select(next));
}
result
}
extern板条箱期货;
使用流;
fn选择所有
哪里
I:迭代器,
I::Item:Stream+'a,
T:a,
E:“a,
{
让mut iter=seq.into_iter();
让mut result=Box::new(iter.next().expect(“得到一个空的流列表”))
as盒;
而让一些(下一个)=iter.next(){
结果=框::新建(结果。选择(下一步));
}
后果
}
当然,有一种更有效的方法来实现这一点。有一个未来的组合,但还没有一个流。也许您可以自己实现它,并将其作为pull请求提交 但通过这种方式,项目将逐个评估,而不是同时评估。是否有
流
版本的期货(无序
)?@penguanwen您的要求不清楚。您需要由内部流生成的项目的流
。如何“同时”交付任何内容?我需要一个无序的缓冲流
。当您组合Future
s的Iterator
时,您可以使用stream::futures\u ordered
或stream::futures\u unordered
,如果您使用后者,只要Future
中的一个可用,流将产生值。当您有一个流
的未来
s时,您可以使用流::流::缓冲区_无序
来实现这一点。但是在我的例子中,流
s的迭代器
很难以这种方式组合。我想不出原因。但是这样的话,这些项目将一个接一个地评估,而不是同时评估。是否有流
版本的期货(无序
)?@penguanwen您的要求不清楚。您需要由内部流生成的项目的流
。如何“同时”交付任何内容?我需要一个无序的缓冲流
。当您组合Future
s的Iterator
时,您可以使用stream::futures\u ordered
或stream::futures\u unordered
,如果您使用后者,只要Future
中的一个可用,流将产生值。当您有一个流
的未来
s时,您可以使用流::流::缓冲区_无序
来实现这一点。但是在我的例子中,流
s的迭代器
很难以这种方式组合。我想不出原因。在futures 0.2(非稳定版本)中,似乎有一个针对streams的应用程序。它似乎是在不使用任何框的情况下实现的。在futures 0.2(非稳定版本)中,似乎有一个for streams。它似乎是在不使用任何Box
的情况下实现的。