Error handling 从vec pop中移除“展开”

Error handling 从vec pop中移除“展开”,error-handling,rust,Error Handling,Rust,这是一个函数(可以工作),它可以生成一个向量,但是其中有一些丑陋的展开,因为它涉及到弹出另一个向量 fn load_into_vec(file_buf: String) -> Vec<Data> { let mut data_vec: Vec<Data> = Vec::new(); for line_iter in file_buf.lines() { let mut line_vec: Vec<&str>

这是一个函数(可以工作),它可以生成一个向量,但是其中有一些丑陋的展开,因为它涉及到弹出另一个向量

fn load_into_vec(file_buf: String) -> Vec<Data> {

    let mut data_vec: Vec<Data> = Vec::new();

    for line_iter in file_buf.lines() {

        let mut line_vec: Vec<&str> = line_iter.split(' ').collect();

        let (t1, t2, t3, t4): (u32, u32, u32, u32) =
        (
            /** ANOTHER WAY TO WRITE THIS? **/
            line_vec.pop().unwrap().trim().parse::<u32>().ok().unwrap(),
            line_vec.pop().unwrap().trim().parse::<u32>().ok().unwrap(),
            line_vec.pop().unwrap().trim().parse::<u32>().ok().unwrap(),
            line_vec.pop().unwrap().trim().parse::<u32>().ok().unwrap()
        );

        let mut data_node = Data::new();
        data_node.load((t4, t3, t2, t1));
        data_vec.push(data_node);
    }

    data_vec
}
fn将\u加载到\u vec(文件\u buf:String)->vec{
让mut data_vec:vec=vec::new();
对于文件_buf.lines()中的行{
让mut line_vec:vec=line_iter.split(“”).collect();
let(t1,t2,t3,t4):(u32,u32,u32,u32)=
(
/**另一种写这个的方式**/
行_vec.pop().unwrap().trim().parse:().ok().unwrap(),
行_vec.pop().unwrap().trim().parse:().ok().unwrap(),
行_vec.pop().unwrap().trim().parse:().ok().unwrap(),
行_vec.pop().unwrap().trim().parse:().ok().unwrap()
);
让mut data_node=data::new();
数据节点负载((t4、t3、t2、t1));
数据向量推送(数据节点);
}
数据向量
}

是否有其他方法可以不使用
unwrap
重写上述块,或者使用
unwrap
在遇到
None
时不会死机?

您可以使用迭代器和
match
编写循环体的更惯用版本。调用
iter.next()
四次匹配,以提取四个整数,而不是收集到中间的
Vec
。如果其中一个
iter.next()
调用失败,您可能会惊慌失措

    let mut iter = line_iter.split(' ')
        .map(str::trim)
        .map(str::parse::<u32>)
        .map(|s| s.expect("could not parse as u32"))
        .fuse();

    let tup = match (iter.next(), iter.next(), iter.next(), iter.next()) {
        (Some(t1), Some(t2), Some(t3), Some(t4)) => (t1, t2, t3, t4),
        _ => panic!("line did not contain at least four numbers"),
    };

    let mut data_node = Data::new();
    data_node.load(tup);

如果让它看起来更漂亮是你所追求的(和恐慌)。。也许有一种方法可以调用unwrap\u或其他内部恐慌的方法吗?我投票将这个问题作为离题的问题来结束,因为关于改进已经运行得更好的代码的问题属于问题。你知道你不应该在迭代器上多次调用
next
,而不检查每一步或融合它。你当然是对的。
file_buf.lines()
    .map(|line_iter| {
        let mut iter = line_iter.split(' ')
            .map(str::trim)
            .map(str::parse::<u32>)
            .map(|s| s.expect("could not parse as u32"))
            .fuse();

        let tup = match (iter.next(), iter.next(), iter.next(), iter.next()) {
            (Some(t1), Some(t2), Some(t3), Some(t4)) => (t1, t2, t3, t4),
            _ => panic!("line did not contain at least four numbers"),
        };

        let mut data_node = Data::new();
        data_node.load(tup);
        data_node
    })
    .collect()
enum MyError {
    NotAnInt,
    TooFewNumbers,
    TooManyNumbers,
}

fn load_into_vec2(file_buf: String) -> Result<Vec<Data>, MyError> {
    file_buf.lines()
        .map(|line_iter| {
            let mut iter = line_iter.split(' ')
                .map(str::trim)
                .map(str::parse::<u32>)
                .fuse();

            match (iter.next(), iter.next(), iter.next(), iter.next()) {
                (Some(Ok(t1)), Some(Ok(t2)), Some(Ok(t3)), Some(Ok(t4))) => if iter.next().is_some() {
                    Err(MyError::TooManyNumbers)
                } else {
                    let mut data_node = Data::new();
                    data_node.load((t1, t2, t3, t4));
                    Ok(data_node)
                },
                (None, _, _, _) |
                (_, None, _, _) |
                (_, _, None, _) |
                (_, _, _, None) => Err(MyError::TooFewNumbers),
                (Some(Err(_)), _, _, _) |
                (_, Some(Err(_)), _, _) |
                (_, _, Some(Err(_)), _) |
                (_, _, _, Some(Err(_))) => Err(MyError::NotAnInt),
            }
        })
        .collect()
}