今天是学习rust的第四天。学习材料为官网的《The Rust Programming Language》本笔记包括第九章错误处理和第十章:generics,traits and lifetimes
Chapter 9, Error Handling
9.1 Unreoverable Errors with panic
当程序出现rust无法处理的bug时,会启动panic
宏,程序打印一个失败信息,unwind并清空栈,随后退出。
unwind有时是一个耗费性的工作,如果想要程序立刻终止,不清空内存,可以在 C a r g o . t o m l Cargo.toml Cargo.toml文件中添加命令:
[profile.release]
panic = 'abort'
此时清空内存的工作交给操作系统。
9.2 Recoverable Errors with Result
result枚举类型:
fn main() {
enum Result<T, E> {
Ok(T),
Err(E),
}
}
T、E为数据类型,T为result返回成功时要输出的数据类型,E为失败时的类型。
fn main(){
let f = File::open("hello.txt");
let f = match f {
//成功则打开文件,不成功则根据错误类型进行判断
Ok(file) => file,
Err(error) => match error.kind(){
//如果是不存在该文件,则创建新文件,其他错误则panic!
ErrorKind::NotFound => match File::create("hello.txt") {
//新创建文件成功返回文件,不成功panic!
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
other_error=> panic!("Problem opening the file: {:?}", other_error)
},
};
}
以上代码可以解决一部分问题,但是三次match的使用使得代码冗长,可读性降低。引入unwrap
解决这个问题。若成功,unwrap
会返回Ok中的值,若失败,unwrap
会调用panic!
use std::fs::File;
fn main() {
let f = File::open("hello.txt").unwrap();
}
另一个方法为expect
,在chapter2使用过,可以返回我们想要的错误信息:
use std::fs::File;
fn main() {
let f = File::open("hello.txt").expect("Failed to open hello.txt");
}
相比之下,由于expect
方法会返回我们规定的错误信息,再调用panic!,因此错误比较容易找到,而unwrap
则较难确定错误的源头。(但是写的时候更简洁)
错误传递:
函数read_username_from _file函数不清楚该如何处理出现的错误,可以将错误传递给调用它的函数,让调用函数处理,成为错误传递
fn read_username_from_file() -> Result<String, io::Error> {
//错误传递
let f = File::open("hello.txt");
let mut f = match f {
Ok(file) => file,
Err(e) => return Err(e),
}