如何将Result类型的迭代器转换为Result<Vec<_>>类型?
如何将Result类型的迭代器转换为包含向量的Result类型?
这个问题其实Rust标准库已经帮我们搞定啦!你完全不需要自己手动实现read_bytes函数——直接用迭代器的collect()方法就可以完成这个转换。
核心解法:使用collect()
当迭代器的Item是Result<T, E>类型时,collect()方法会自动完成这种“从Result迭代器到Result包裹的Vec”的转换:
- 如果迭代过程中遇到任何一个
Err,整个转换会立刻终止并返回这个错误; - 如果所有元素都是
Ok,就会把所有Ok内部的值收集成一个Vec<T>,再用Ok包裹后返回。
修改后的代码示例如下:
use std::io::{Read, Result}; use std::fs::File; fn main() { let f = File::open("some-file").unwrap(); let bytes = f.bytes(); // 直接调用collect()就能得到Result<Vec<u8>> let byte_vector: Result<Vec<u8>> = bytes.collect(); } // 如果一定要保留read_bytes函数,内部直接调用collect即可 fn read_bytes<I: Iterator<Item=Result<u8>>>(bytes: I) -> Result<Vec<u8>> { bytes.collect() }
手动实现(理解底层逻辑)
如果你想知道这个转换的底层原理,也可以手动实现一遍,逻辑其实很直观:
fn read_bytes_manual<I: Iterator<Item=Result<u8>>>(mut bytes: I) -> Result<Vec<u8>> { let mut vec = Vec::new(); while let Some(item) = bytes.next() { // 用?操作符处理Result:遇到错误直接返回,否则取出值存入向量 vec.push(item?); } Ok(vec) }
这个手动实现和标准库collect()的逻辑一致:遍历迭代器的每个元素,处理每个Result,遇到错误就提前返回,否则收集所有正确的值到Vec中,最后返回Ok包裹的Vec。
内容的提问来源于stack exchange,提问作者fabiim
相关产品推荐
相关产品推荐

