Login
Create new posts
在 Rust 中我们采用 Result<R, E>
的类型处理错误,这样(初学者)就特别容易出现错误处理嵌套地狱,比如如下一段利用 libgit2
读取一些 git repo 信息的代码:
match Repository::open(first_arg) {
Ok(repo) => {
// println!("{:?}", repo);
match repo.find_remote("origin") {
Ok(mut origin) => {
println!("success!");
match repo.branches(Some(BranchType::Local)) {
Ok(branches) => {
for branch_result in branches {
match branch_result {
Ok((branch, branch_type)) => {
println!("Iterating at {:?}", branch.name());
match branch.name() {
Ok(Some(branch_name)) => {
origin.fetch(&[branch_name], None, None);
}
_ => {
println!("Error!")
}
}
}
Err(e) => {
println!("{:?}", e)
}
}
}
}
Err(e) => {
println!("{:?}", e)
}
}
}
Err(e) => {
println!("{:?}", e)
}
};
match repo.remotes() {
Ok(remotes) => {
for remote in remotes.iter() {
println!("{:?}", remote);
}
}
Err(e) => {
println!("{:?}", e);
}
};
println!("hee");
}
Err(e) => panic!("failed to open: {}", e),
};
每一层都进行 match
,导致出现了极不可读的嵌套。
那么,正确的做法是什么呢?如上一段代码,优雅的写法是什么?
具体解释见 std::ops::Try
use failure::Error;
fn some_fn() -> Result<(), Error> {
let repo = Repository::open(first_arg)?;
let mut origin = repo.find_remote("origin")?;
let branches = repo.branches(Some(BranchType::Local))?;
for branch_result in branches {
let (branch, branch_type) = branch_result?;
if let Some(branch_name) = branch.name()? {
origin.fetch(&[branch_name], None, None);
}
}
let remotes = repo.remotes()?;
for remote in remotes.iter() {
println!("{:?}", remote);
}
Ok(())
}