rust - 当对 None 值调用 unwrap 时,try 块中的代码仍然会出现恐慌
问题描述
#![feature(try_blocks)]
pub fn is_valid(code: &str) -> bool {
let result: Result<bool, ()> = try {
code.chars()
.filter(|x| !x.is_whitespace())
.map(|x| x.to_digit(10).unwrap())
.rev()
.enumerate()
.map(|(i, num)| match i % 2 != 0 {
true => {
let doubled = 2 * num;
match doubled > 9 {
true => doubled - 9,
false => doubled,
}
}
false => num,
})
.sum::<u32>()
% 10
== 0
};
match result {
Ok(value) => value,
Err(_) => false,
}
}
在某些输入上,这个程序会出现恐慌,我不明白为什么。to_digit
返回一个,Option
但它被解包,并且None
应该被try
块捕获。我的理解是,如果.unwrap
在一个值上调用了None
,try 块将返回 a Result::Error
,最终match
将转换为false
。
我是 Rust 的新手!
我确实尝试x.to_digit(10).ok_or("Error").unwrap()
将它变成 aResult
而不是 a Option
,但它没有任何区别。
解决方案
我的理解是,如果在 None 值上调用 .unwrap,try 块将返回 Result::Err
实际上没有:来自文档:
如果 self 值等于 None 会发生恐慌。
'Panic' 与返回Result::Err
. 恐慌旨在用于不可恢复的错误,而返回 aResult::Err
用于日常潜在的可恢复错误。有关差异的更多讨论,请参阅 rust book 中的错误处理章节。
正如您所暗示的那样,unwrap
您可以使用ok_or
将其转换Option
为 a Result
:
x.to_digit(10).ok_or("Error")?
请注意,我放了一个“?” 最后,而不是unwrap
您尝试过的。的效果?
是:
- 如果值为 a
Result::Err
则从封闭函数或 try 块返回 - 如果值为 a
Result::Ok
那么它被解包。
它脱糖是这样的:
match x.to_digit(10).ok_or("Error") {
Err(e) => return Err(e),
Ok(v) => v
}
正如评论中的某些人所提到的,如果您是 rust 新手,最好远离不稳定的功能,尽管我认为这不是导致此问题的原因。
推荐阅读
- android - 启动 APK 安装程序 Kitkat
- java - 如何解决 ClassNotFoundException:com.beust.jcommander.ParameterException
- scala - 为什么一个演员要开始两次?
- javascript - 使用 MochaJS 在 setInterval() 中测试对外部函数的回调
- java - 通过蓝牙 (Android-Studio) 向 OBD-ii 设备发送数据时应用程序崩溃
- progressive-web-apps - 取消发送的 Web 推送通知
- d3.js - 如何在 D3.js 中动态翻译 SVG 组?
- python-2.7 - 如果excel文件不存在如何创建
- python-3.x - 如何从包含前两列组合的熊猫数据框中删除行
- algorithm - Photoshop调色刀效果背后的算法是什么?