如何从含列表的Result流中直接收集扁平化Vec?
优化Rust流处理:直接扁平化嵌套列表输出
原代码通过两次收集(先得到Vec<Vec<i32>>再扁平化)生成结果,我们可以直接操作流来避免中间步骤,一次收集得到目标输出。
方案一:用try_flatten扁平化流的流
将每个元素生成的Vec包装为子流,再通过try_flatten直接扁平化流的流:
use futures::{stream, TryStreamExt}; let output: Vec<i32> = stream::iter(vec![1, 2, 3]) .then(|val| async move { // 将Vec转换为子流并包裹在Ok中 Ok(stream::iter(vec![val * 10, val * 10 + 1])) }) .try_flatten() // 扁平化嵌套的流结构 .try_collect() // 直接收集为一维Vec .await?; assert_eq!(output, vec![10, 11, 20, 21, 30, 31]);
方案二:用flat_map_ok处理嵌套列表
利用flat_map_ok将每个Ok包裹的Vec转换为子流,同时自动完成扁平化并保留错误处理逻辑:
use futures::{stream, StreamExt, TryStreamExt}; let output: Vec<i32> = stream::iter(vec![1, 2, 3]) .then(|val| async move { Ok(vec![val * 10, val * 10 + 1]) }) .flat_map_ok(stream::iter) // 将Vec转换为子流并扁平化 .try_collect() .await?; assert_eq!(output, vec![10, 11, 20, 21, 30, 31]);
原try_flatten尝试失败的原因
try_flatten的作用是扁平化流的流,要求流的每个元素是Result<Stream<Item = Result<T, E>>, E>类型。原代码中流的输出是Result<Vec<i32>, ()>,并非包含子流的Result,因此无法直接使用try_flatten。必须先将Vec转换为Stream,才能满足try_flatten的类型要求。
内容的提问来源于stack exchange,提问作者klefevre
相关产品推荐
相关产品推荐

