如果已知选项变量为非None
,则通常可以写入:
let var = option_var.unwrap();
在我碰到的一个案例中,这引起了一个关于摆脱借来的背景的错误。
if let Some(var) = option_var { ... }
(很方便,因为它也允许Some(ref mut var) = option_var
。
这是有效的,但在这种情况下,我不希望这是一个if
语句。
写入let Some(var) = option_var;
失败,错误“模式None
未涵盖”。
要明确这个问题不是关于借用的背景。
let Some(var) = option;
语法是否可以在已知它不是None
的情况下使用?解决“模式None
未涵盖”警告?或者这只是在if
声明之外不支持?
答案 0 :(得分:6)
鉴于以下情况:
v1, v2 = input().split()
v1, v2 = int(v1), int(v2)
res = v1 ^ v2
print(res)
错误[E0005]:本地绑定中的可反射模式:
fn main() { let foo = Some(1); let Some(bar) = foo; }
未涵盖
None
引入了一种模式; let Some(x) = y
和let
语句和函数参数是模式匹配上下文,但由于在这种情况下模式不包含其他可能的情况,因此它不是有效的模式匹配上下文。
match
语句适用的唯一上下文是if let
表达式和while let
循环。
如果您确定(例如,使用较早的let Some(x) = y
或“手动”引入),则assert!()
无法使用None
,您只需使用unwrap()
。
答案 1 :(得分:2)
我刚遇到类似枚举的类似问题:
let SomeEnum::First(first) = item;
我知道item
是SomeEnum::First
。但是Rust不会让我编译。
一种绕过此问题的方法是使用这样的宏:
macro_rules! unwrap {
($enum:path, $expr:expr) => {{
if let $enum(item) = $expr {
item
} else {
panic!()
}
}};
}
您可以像这样调用unwrap!
:
let first = unwrap!(SomeEnum::First, item);
PS。我在测试中使用它。它有助于缩短测试时间。