在Rust中,我们会经常使用Result<xxxx,xxxx>来返回正确结果和错误信息。但是,在这样的需求下,我们会遇到一个麻烦事:函数A内部要调用多个函数,并且只要其中某个步骤出错,当前函数A就直接返回这个错误信息。
在上面这个场景下,我们会编写许多这样的代码:
代码语言:javascript复制use std::fs::File;
use std::io::prelude::*;
use std::io;
struct Info {
name: String,
age: i32,
rating: i32,
}
fn write_info(info: &Info) -> io::Result<()> {
// Early return on error
let mut file = match File::create("my_best_friends.txt") {
Err(e) => return Err(e),
Ok(f) => f,
};
if let Err(e) = file.write_all(format!("name: {}n", info.name).as_bytes()) {
return Err(e)
}
if let Err(e) = file.write_all(format!("age: {}n", info.age).as_bytes()) {
return Err(e)
}
if let Err(e) = file.write_all(format!("rating: {}n", info.rating).as_bytes()) {
return Err(e)
}
Ok(())
}
冗长的错误处理代码显得非常不雅观,为了解决这个问题,我们可以使用“问号运算符”,来简化这个流程:
代码语言:javascript复制use std::fs::File;
use std::io::prelude::*;
use std::io;
struct Info {
name: String,
age: i32,
rating: i32,
}
fn write_info(info: &Info) -> io::Result<()> {
let mut file = File::create("my_best_friends.txt")?;
// Early return on error
file.write_all(format!("name: {}n", info.name).as_bytes())?;
file.write_all(format!("age: {}n", info.age).as_bytes())?;
file.write_all(format!("rating: {}n", info.rating).as_bytes())?;
Ok(())
}
在上述代码中,以“?”结尾的表达式,将会自动unwrap Ok()的成功值,如果Result<>是Err,那就会自动吧把这个Err向上传递,也就是,当前函数直接return这个错误值。
本文引用:https://doc.rust-lang.org/std/result/