更新时间:2023-11-11 20:06:46
Rust 通常通过两种方式解决错误:
Rust generally solves errors in two ways:
不可恢复的错误.一旦你恐慌!
,就是这样.您的程序或线程中止,因为它遇到了无法解决的问题,并且违反了它的不变量.例如.如果您在 UTF-8 字符串中发现无效序列.
Unrecoverable errors. Once you panic!
, that's it. Your program or thread aborts because it encounters something it can't solve and its invariants have been violated. E.g. if you find invalid sequences in what should be a UTF-8 string.
可恢复的错误.在某些文档中也称为失败.你没有恐慌,而是发出一个 Option
或 Result
.在这些情况下,您可以分别选择有效值 Some(T)
/Ok(T)
或无效值 None
/错误(E)代码>.一般None
作为null
的替换,表示值缺失.
Recoverable errors. Also called failures in some documentation. Instead of panicking, you emit a Option<T>
or Result<T, E>
. In these cases, you have a choice between a valid value Some(T)
/Ok(T)
respectively or an invalid value None
/Error(E)
. Generally None
serves as a null
replacement, showing that the value is missing.
现在是困难的部分.申请.
Now comes the hard part. Application.
有时处理 Option
是一件头疼的事,您几乎可以保证得到一个值而不是错误.
Sometimes dealing with an Option
is a pain in the neck, and you are almost guaranteed to get a value and not an error.
在这些情况下,使用 unwrap
完全没问题.unwrap
将 Some(e)
和 Ok(e)
变成 e
,否则会 panic.Unwrap 是一种将可恢复错误变为不可恢复的工具.
In those cases it's perfectly fine to use unwrap
. unwrap
turns Some(e)
and Ok(e)
into e
, otherwise it panics. Unwrap is a tool to turn your recoverable errors into unrecoverable.
if x.is_some() {
y = x.unwrap(); // perfectly safe, you just checked x is Some
}
在 if
块内,解包完全没问题,因为它永远不会恐慌,因为我们已经用 x.is_some()
.
Inside the if
-block it's perfectly fine to unwrap since it should never panic because we've already checked that it is Some
with x.is_some()
.
如果您正在编写库,不鼓励使用 unwrap
,因为当它发生恐慌时,用户无法处理错误.此外,未来的更新可能会更改不变量.想象一下,如果上面的例子有 if x.is_some() ||always_return_true()
.不变量会改变,unwrap
可能会恐慌.
If you're writing a library, using unwrap
is discouraged because when it panics the user cannot handle the error. Additionally, a future update may change the invariant. Imagine if the example above had if x.is_some() || always_return_true()
. The invariant would changed, and unwrap
could panic.
什么是 ?
运算符或 try!
宏?一个简短的解释是它要么返回 Ok()
内的值,要么过早地返回错误.
What's the ?
operator or the try!
macro? A short explanation is that it either returns the value inside an Ok()
or prematurely returns error.
以下是运算符或宏扩展为的简化定义:
Here is a simplified definition of what the operator or macro expand to:
macro_rules! try {
($e:expr) => (match $e {
Ok(val) => val,
Err(err) => return Err(err),
});
}
如果你像这样使用它:
let x = File::create("my_file.txt")?;
let x = try!(File::create("my_file.txt"));
它会转换成这样:
let x = match File::create("my_file.txt") {
Ok(val) => val,
Err(err) => return Err(err),
};
缺点是你的函数现在返回Result
.
The downside is that your functions now return Result
.
Option
和 Result
有一些方便的方法,允许以可理解的方式链接和处理错误.and
、and_then
、or
、or_else
、ok_or
、 等方法map_err
等
例如,您可以有一个默认值,以防您的值被破坏.
For example, you could have a default value in case your value is botched.
let x: Option<i32> = None;
let guaranteed_value = x.or(Some(3)); //it's Some(3)
或者如果你想把你的 Option
变成一个 Result
.
Or if you want to turn your Option
into a 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"));
这只是您可以做的事情的简要介绍.如需更多解释,请查看:
This is just a brief skim of things you can do. For more explanation, check out: