Vit*_*upt 14 error-handling rust
我注意到Rust没有例外.如何在Rust中进行错误处理以及常见的陷阱是什么?有没有办法通过加注,捕获,重新加注和其他东西来控制流量?我发现这方面的信息不一致.
Dan*_*ath 28
Rust通常以两种方式解决错误:
不可恢复的错误.一旦你panic!,就是这样.您的程序或线程因为遇到无法解决的问题而中止,并且违反了其不变量.例如,如果您在UTF-8字符串中找到无效序列.
可恢复的错误.在某些文档中也称为失败.而不是恐慌,你发出一个Option<T>或Result<T, E>.在这些情况下,您可以分别选择有效值Some(T)/ Ok(T)或无效值None/ Error(E).通常None用作null替代品,表明缺少价值.
现在来了困难的部分.应用.
有时处理Option是一个痛苦的脖子,你几乎可以保证得到一个值,而不是一个错误.
在这些情况下,使用起来非常好unwrap.unwrap转Some(e)和Ok(e)成e,否则恐慌.展开是一种将可恢复错误转变为不可恢复的工具.
if x.is_some() {
y = x.unwrap(); // perfectly safe, you just checked x is Some
}
Run Code Online (Sandbox Code Playgroud)
内部if-阻塞它是完美的罚款解开,因为它不应该恐慌,因为我们已经检查,这是Some有x.is_some().
如果您正在编写库,unwrap则不鼓励使用,因为当它发生恐慌时,用户无法处理错误.此外,未来的更新可能会更改不变量.想象一下,如果上面的例子有if x.is_some() || always_return_true().不变量会改变,unwrap可能会引起恐慌.
?运算符/ try!宏什么是?运营商或try!宏?一个简短的解释是,它要么返回一个值,Ok()要么过早地返回错误.
以下是运算符或宏扩展到的简化定义:
macro_rules! try {
($e:expr) => (match $e {
Ok(val) => val,
Err(err) => return Err(err),
});
}
Run Code Online (Sandbox Code Playgroud)
如果你这样使用它:
let x = File::create("my_file.txt")?;
Run Code Online (Sandbox Code Playgroud)
let x = try!(File::create("my_file.txt"));
Run Code Online (Sandbox Code Playgroud)
它会将其转换为:
let x = match File::create("my_file.txt") {
Ok(val) => val,
Err(err) => return Err(err),
};
Run Code Online (Sandbox Code Playgroud)
缺点是您的功能现在返回Result.
Option并Result有一些方便的方法,允许以可理解的方式链接和处理错误.方法,如and,and_then,or,or_else,ok_or,map_err,等.
例如,如果您的值被拙劣,您可以使用默认值.
let x: Option<i32> = None;
let guaranteed_value = x.or(Some(3)); //it's Some(3)
Run Code Online (Sandbox Code Playgroud)
或者如果你想把你Option变成一个Result.
let x = Some("foo");
assert_eq!(x.ok_or("No value found"), Ok("foo"));
let x: Option<&str> = None;
assert_eq!(x.ok_or("No value found"), Err("No value found"));
Run Code Online (Sandbox Code Playgroud)
这只是您可以做的事情的简要描述.有关更多说明,请查看:
| 归档时间: |
|
| 查看次数: |
5226 次 |
| 最近记录: |