【发布时间】:2020-05-02 07:34:23
【问题描述】:
我正在学习 Rust,我遇到了以下模式,它将 Result<Vec<_>, _>s 的迭代器折叠成一个大的 Vec<_>,如果迭代器的任何结果失败,则失败:
fn accumulate<T, E>(it: impl Iterator<Item = Result<Vec<T>, E>>) -> Result<Vec<T>, E> {
let mut result = Vec::new();
for mut ts in it {
result.append(&mut ts?)
}
Ok(result)
}
我假设可以编写这个函数的一个非常短的“函数式”版本,我正在努力寻找它。从道德上讲,我想做类似的事情
it.map(|v| v?.into_iter()).flatten().collect()
但这不会进行类型检查。通过运行小示例,我认为flatten 的意义在于默默地删除错误结果,但我想以某种方式“将flatten 映射到Results 下”。我也知道,一般来说,你不能收集类型的迭代器
impl Iterator<Item = Result<impl Iterator<Item = T>, Error>>
进入迭代器
Result<impl Iterator<Item = impl Iterator<Item = T>>, Error>
因为您需要在外部迭代器中实际完成所有计算才能知道最终结果。尽管如此,在这种特殊情况下,当您想.flatten() 然后.collect() 之后,您似乎可以做到这一点。
最后,我可以看到collect() 给了我一种从it 构建向量向量的方法,然后我可以将该向量展平为我想要的单个大向量。但这有很多不必要的内存分配。
标准库能否帮助您以高效的 Rust-ic 方式做到这一点?
【问题讨论】:
-
我个人认为命令式很好。
标签: rust functional-programming iterator