其中T 和E是泛型类型参数,可以借助泛型将Result类型用于很多场景。实际使用Result类型是为了便于进行错误信息的向上传递,也可以进行错误处理。对于常见的可能产生错误的操作,一般都会返回 Result 类型,比如打开文件,文件读写等。
fn get_file(filename: &str) -> String {
let f = File::open(filename);
let mut f = match f {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create(filename) {
Ok(fc) => fc,
Err(e) => panic!("Create file failure: {:?}", e),
}
other_error => panic!("There is a problem in opening file:{:?}", other_error),
},
};
let mut contents = String::new(); // Pay atten: read_to_string is a method of &mut File
match f.read_to_string(&mut contents) {
Ok(_) => (),
Err(error) => panic!("Read file error:{:?}", error),
};
contents
}
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let f = File::open("hello.txt").map_err(|error| {
if error.kind() == ErrorKind::NotFound {
File::create("hello.txt").unwrap_or_else(|error| {
panic!("Tried to create file but there was a problem: {:?}", error);
})
} else {
panic!("There was a problem opening the file: {:?}", error);
}
});
}
2.2 unwrap and expect
Result<T, E>类型定义了很多方法处理各种情况,可以使用unwrap方法得到其成员值。
use std::fs::File;
fn main() {
let f = File::open("hello.txt").unwrap();
}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error {
repr: Os { code: 2, message: "No such file or directory" } }',
src/libcore/result.rs:906:4
thread 'main' panicked at 'Failed to open hello.txt: Error { repr: Os { code:
2, message: "No such file or directory" } }', src/libcore/result.rs:906:4
因为这个错误信息以我们指定的文本开始,Failed to open hello.txt,将会更容易找到代码中的错误信息来自何处。如果在多处使用 unwrap,则需要花更多的时间来分析到底是哪一个 unwrap 造成了 panic,因为所有的 unwrap 调用都打印相同的信息。
use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}