rap*_*2-h 16 error-handling rust
在运行时很容易崩溃unwrap
:
fn main() {
c().unwrap();
}
fn c() -> Option<i64> {
None
}
Run Code Online (Sandbox Code Playgroud)
结果:
Compiling playground v0.0.1 (file:///playground)
Running `target/debug/playground`
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', ../src/libcore/option.rs:325
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: Process didn't exit successfully: `target/debug/playground` (exit code: 101)
Run Code Online (Sandbox Code Playgroud)
是unwrap
唯一专为快速测试和证明的概念?
我不能肯定"我的程序不会崩溃,所以我可以使用unwrap
",如果我真的想panic!
在运行时避免,我认为避免panic!
是我们想要的生产应用程序.
换句话说,如果我使用,我可以说我的程序是可靠的unwrap
吗?或者unwrap
即使案件看似简单,我也必须避免吗?
我读到了这个答案:
当您确定没有错误时,最好使用它.
但我认为我不能"肯定".
我不认为这是一个意见问题,而是一个关于Rust核心和编程的问题.
Luk*_*odt 26
而整个"错误处理" -topic非常复杂,基于经常认为,这一问题实际上可以在这里找到答案,因为锈病而窄的理念.那是:
panic!
对于编程错误("错误")Result<T, E>
及Option<T>
对预期和可恢复的错误人们可以想到的unwrap()
是转换这两种类型的错误之间(这是将可恢复的错误到panic!()
).当你写unwrap()
你的程序时,你说:
此时,
None
/Err(_)
值是编程错误,程序无法从中恢复.
例如,假设您正在使用a HashMap
并且想要插入一个您可能希望稍后变异的值:
age_map.insert("peter", 21);
// ...
if /* some condition */ {
*age_map.get_mut("peter").unwrap() += 1;
}
Run Code Online (Sandbox Code Playgroud)
在这里我们使用unwrap()
,因为我们可以确定该键具有值.如果它没有,甚至更重要,那将是一个编程错误:它不是真正可以恢复的.当你在那一点上没有钥匙的价值时你会怎么做"peter"
?再试一次插入......?
但是您可能知道,Rust的标准库中有一个漂亮的地图entry
API.使用该API,您可以避免所有这些unwrap()
.这适用于几乎所有情况:您可以经常重构您的代码以避免unwrap()
!只有极少数情况下才有办法解决.但是如果你想发出信号就可以使用它:在这一点上,这将是一个编程错误.
最近有一篇关于"错误处理"主题的相当受欢迎的博客文章,其结论类似于Rust的哲学.它相当长但值得一读:"错误模型".这是我尝试总结与此问题相关的文章:
总结:unwrap()
当您确定所获得的可恢复错误实际上在此时无法恢复时使用.在受影响的线上方的评论中解释"为什么?"的奖励积分;-)
换句话说,如果我使用unwrap,我可以说我的程序是可靠的吗?或者即使案件看起来很简单,我也必须避免打开包裹吗?
我认为unwrap
明智地使用是你必须学会处理的东西,它不能只是避免.
我的修辞问题是:
(1)就像解包,索引恐慌,如果你违反合同并尝试索引越界.这将是程序中的一个错误,但它没有像调用那样引起注意unwrap
.
(2)如果除数为零,就像解包,整数除法恐慌.
(3)与unwrap不同,添加不检查发布版本中的溢出,因此它可能会静默导致环绕和逻辑错误.
当然,有一些策略可以处理所有这些,而不会在代码中留下恐慌的情况,但是许多程序只是简单地使用例如边界检查.
这里有两个问题合二为一:
panic!
生产中的使用是否可接受unwrap
生产中的使用是否可接受panic!
是 Rust 中用来表示无法恢复的情况/违反假设的工具。它可用于使程序崩溃,而该程序在遇到此故障时可能无法继续运行(例如 OOM 情况),也可用于解决编译器知道它无法执行(目前)的问题。
unwrap
这是一种便利,在生产中最好避免这种情况。问题unwrap
是它没有说明违反了哪个假设,最好使用expect("")
功能相同的假设,但也会给出出错的线索(无需打开源代码)。
归档时间: |
|
查看次数: |
1555 次 |
最近记录: |