您可以使用迭代器和match
來編寫更加慣用的循環體。而不是收集到中間Vec
,你匹配四次調用iter.next()
,以提取你的四個整數。如果其中一個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);
我甚至會去儘可能重寫整個功能:
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()
}
如果讓它看起來更漂亮是你所有的(而且恐慌)..也許[這樣的東西就足夠了嗎?](http://play.integer32.com/?gist=462d0e57bedae7a31381cee670ba6688&version=stable ) –
有沒有辦法在內部調用unwrap_or_else? – GoldenChrysanthem
我投票結束這個問題作爲題外話,因爲有關改進**已經工作**更好的代碼的問題屬於[Code Review.SE](http://meta.codereview.stackexchange.com/questions/5777 /一個引導到代碼審查換堆棧上溢用戶)。 – Shepmaster