大家好,我是梦兽编程。欢迎回来与梦兽编程一起刷Rust的系列。
这是由 Google 的 Android开发团队的分享Rust课程。本课程涵盖了 Rust 的方方面面,从基本语法到泛型和错误处理等高级主题。
该课程的最新版本可以在 google.github.io/comprehensi…
如果你喜欢看梦兽编程的版本可以订阅跟着谷歌安卓团队学Rust订阅最新内容,梦兽编程也期待大家关注我的个人网站。
加入梦兽编程微信群,公众号回复111即可加入交流群与梦兽进行交流。
Result
在之前我们介绍可以使用Option避免程序出现空指针导致程序的崩溃。但有时候可能因为一个函数会没有做出反应而导致程序崩溃。
例如,如果因为打开一个并不存在的文件而失败,此时我们可能想要创建这个文件,而不是终止进程。
这个时候你就可以使用Result处理这种问题。在Rust中使用Result有点类似golang err。它只有成功和失败两个类型,并不会像Option那样匹配多个Some。
在golang中你可以看到很多err的处理
filePath := "path/to/file.txt"
file, err := os.Open(filePath)
if err != nil {
fmt.Println("打开文件时发生错误:", err)
return
}
在Rust中你可以这么理解会比较容易上手。
Result 枚举类型
它又一个Ok和Err组成,按照约定,预期结果是 “Ok”,而意外结果是 “Err”。
enum Result<T, E> {
Ok(T),
Err(E),
}
还是以上面golang的例子,在Rust中你可以这么编码。
在没有学习unwrap和expect之前,我们打开文件的时候需要自己处理异常。先获取open后的Result file对象,对其进行match操作。
如果我们确定操作一定会成功,可以使用unwrap方法直接获取Ok中的值;如果我们期望操作成功但有可能失败,可以使用expect方法指定一个错误提示信息。
use std::fs::File;
use std::io::Read;
fn main() {
let file: Result<File, std::io::Error> = File::open("path/to/file.txt");
match file {
Ok(mut file) => {
let mut contents = String::new();
if let Ok(bytes) = file.read_to_string(&mut contents) {
println!("Dear diary: {contents} ({bytes} bytes)");
} else {
println!("Could not read file content");
}
}
Err(err) => {
println!("The diary could not be opened: {err}");
}
}
}
我们在看一个之前使用Option的例子,如果使用Result可以这么编码。
fn divide(x: i32, y: i32) -> Result<i32, String> {
if y == 0 {
Err(String::from("division by zero"))
} else {
Ok(x / y)
}
}
fn main() {
let result = divide(10, 0);
match result {
Ok(value) => {
println!("Result: {}", value);
},
Err(error) => {
println!("Error: {}", error);
}
}
}
Result类型的应用场景
梦兽编程结合常用开发场景认为可以处理以下场景:
- 文件读写操作:可以使用Result类型来处理文件读写可能出现的错误,比如文件不存在或权限不足等
- 网络请求:对于网络请求,可能会出现连接超时、服务器错误等情况,Result类型可以帮助我们处理这些错误
- 数据库操作:在使用数据库进行增删改查时,可能会出现连接失败、查询语句错误等情况,Result类型可以帮助我们处理这些错误
总结Result类型的优势和注意事项
- Result类型强制我们在编码时考虑错误处理的情况,提高程序的健壮性
- 使用Result类型能够明确和清晰地处理操作成功和失败的情况
- 需要注意正确处理Result类型的所有可能结果,避免出现未处理的错误导致程序崩溃或不可预期的行为
总结Result类型的重要性和灵活性,在编写Rust程序时充分利用Result类型进行错误处理,提高代码的可靠性和可维护性
参考资料
[1]
google.github.io/comprehensi…: google.github.io/comprehensi…
本文使用 markdown.com.cn 排版