`let Some(var)= option;`语法可以用在已知它不是'None`的情况下吗?

时间:2017-01-10 16:37:09

标签: rust variable-assignment optional

如果已知选项变量为非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声明之外不支持?

2 个答案:

答案 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) = ylet语句和函数参数是模式匹配上下文,但由于在这种情况下模式不包含其他可能的情况,因此它不是有效的模式匹配上下文。

match语句适用的唯一上下文是if let表达式和while let循环。

如果您确定(例如,使用较早的let Some(x) = y或“手动”引入),则assert!()无法使用None,您只需使用unwrap()

答案 1 :(得分:2)

我刚遇到类似枚举的类似问题:

let SomeEnum::First(first) = item;

我知道itemSomeEnum::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。我在测试中使用它。它有助于缩短测试时间。