gpt4 book ai didi

error-handling - 从 vec pop 中移除 unwrap

转载 作者:行者123 更新时间:2023-11-29 08:00:29 24 4
gpt4 key购买 nike

这是一个生成事物向量的函数(有效),但其中有一些丑陋的解包,因为它涉及弹出另一个向量。

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
}

是否有另一种方法可以在不使用 unwrap 的情况下重写上述代码块,或者使用 unwrap 以使其在遇到 None< 时不会崩溃的方式?

最佳答案

您可以使用迭代器和match 来编写更符合习惯的循环体版本。不是收集到中间 Vec,而是匹配调用 iter.next() 四次,以提取四个整数。如果其中一个 iter.next() 调用没有成功,您可能会感到 panic 。

    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);

我什至会重写整个函数:

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()

更好的方法是让函数返回一个 Result 来指示何时发生了错误:

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()
}

关于error-handling - 从 vec pop 中移除 unwrap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41694896/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com