标签:std use Ok Result File 错误处理 panic rust
rust 错误处理概述
-
rust的可靠性:错误处理
- 大部分情况下:在编译时提示错误
-
错误的分类
-
可恢复
- 例如文件未找到,可再次尝试
-
不可恢复
- bug,例如访问的索引超出范围
-
-
rust没有类似异常的机制
- 可恢复错误, Result<T, E>
- 不可恢复错误,panic!宏
不可恢复的错误与panic!
-
当panic!宏执行:
- 你的程序会打印一个错误信息
- 展开(unwind)、清理调用栈(Stack)
- 退出程序
-
默认情况下,panic!发生:
-
程序展开调用栈(工作量大)
- Rust沿着调用栈往回走
- 清理每个遇到的函数中的数据
-
或立即终止调用栈
- 不进行清理,直接停止程序
- 内存需要OS进行清理
-
-
想让二进制文件更小,把设置从“展开“改为“中止“:
- 在Cargo.toml中适当的profile部分设置:
- panic = ‘abort’
- 在Cargo.toml中适当的profile部分设置:
[package]
name = "demo"
version = "0.1.0"
authors = ""
edition = "2018"
[dependencies]
[profile.release]
panic = 'abort'
使用panic!产出的回溯信息
-
panic!可能出现在:
- 我们写的代码中
- 我们所依赖的代码中
-
可通过调用panic!的函数的回溯信息来定位引起问题的代码
-
通过设置环境变量RUST_BACKTRACE可得到回溯信息
-
为了获取带有调试信息的回溯,必须启用调试符号(不带 --release)
Result与可恢复错误
Result枚举
-
enum Result<T, E>{
Ok(T),
Err(E),
}
T:操作成功情况下,Ok变体里返回的数据类型
E:操作失败情况下,Err变体里返回的错误的类型
use::fs::File;
fn main(){
let f = File::open("hello.txt");
}
处理Result的一种方式:match表达式
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
匹配不同的错误
use std::fs::File;
fn main(){
let f = File::open("hello.txt");
let f = match f{
Ok(file) => file,
Err(error) => match error.kind(){
ErrorKind::NotFind => match File::create("hello.txt"){
Ok(fc) => fc,
Err(e) => panic!("Error creating file:{:?}", e),
},
other_error => panic!("Error opening the file:{:?}", other_errpr),
}
};
}
unwrap:match表达式的一个快捷方法:
-
如果Result结果是Ok,返回Ok里面的值
-
如果Result结果是Err,调用panic!宏
use std::fs::File;
fn main(){
let f = File::open("hello.txt").unwrap();
}
expect:和unwrap类似,但可以指定错误信息
use std::fs::File;
fn main(){
let f = File::open("hello.txt").expect("文件不存在!");
}
传播错误
- 在函数出处理错误
- 将错误返回给调用者
use std::fs::File;
use std::io;
use std::io::read;
fn read_username_from_file() -> Result<String, io::err> {
let f = File::open("hello.txt");
let mut f = match f{
Ok(file) => file,
Err(e) => return Err(e),
};
let mut s = String::new();
match f.read_to_string(&mut s){
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
?运算符
- ?运算符:传播错误的一种快捷方式
- 如果Result是Ok:Ok中的值就是表达式的结果,然后继续执行程序
- 如果Result是Err:Err就是整个函数的返回值,就像使用了return
use std::fs::File;
use std::io;
use std::io::Read;
fn read_username_from_file() -> Result<String, io::Error> {
let f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
?与from函数
-
Trait std::convert::From 上的from函数:
- 用于错误之间的转换
-
当?所应用的错误,会隐式的被from函数处理
-
当?调用from函数时:
-
它所接收的错误类型会被转化为当前函数返回类型所定义的错误类型
EA->EB, EA实现from函数,返回值为EB
-
-
用于:针对不同错误原因,返回同一种错误类型
- 只要每个错误类型实现了转换为所返回的错误类型的from函数
链式调用
use std::fs::File;
use std::io;
use std::io::Read;
fn read_username_from_file() -> Result<String, io::Error> {
let mut s = String::new();
File::open("hello.txt")?.read_to_string(&mut s)?;
Ok(s)
}
?运算符只能用于返回值为Result的函数
?运算符与main函数
- main函数返回类型是:()
- main函数的返回类型也可以是: Result<T, E>
- Box 是trait对象:
- 简单理解:“任何可能的错误类型”
何时使用panic!
总体原则
- 在定义一个可能失败的函数时,优先考虑返回Result
- 否则返回panic!
标签:std,use,Ok,Result,File,错误处理,panic,rust 来源: https://blog.csdn.net/fly_tzf/article/details/120434915
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。