Reputation: 48178
When an option variable is known to be non-None
, its normally fine to write:
let var = option_var.unwrap();
In one case I ran into, this caused an error about moving out of borrowed context.
if let Some(var) = option_var { ... }
(Handy since it allows Some(ref mut var) = option_var
too).
This works, however in this case I don't want this to be an if
statement.
Writing let Some(var) = option_var;
fails with the error "pattern None
not covered".
To be clear this question isn't about borrowed context.
Can the let Some(var) = option;
syntax be used in a situation where it's known that it's not None
? Resolving the "Pattern None
not covered" warning? Or is this simply not supported outside an if
statement?
Upvotes: 1
Views: 4078
Reputation: 1933
I've just encountered a similar problem with enum like:
let SomeEnum::First(first) = item;
I know item
is SomeEnum::First
. But Rust won't let me compile.
One way to bypass this problem is to use a macro like this:
macro_rules! unwrap {
($enum:path, $expr:expr) => {{
if let $enum(item) = $expr {
item
} else {
panic!()
}
}};
}
And you can invoke unwrap!
like this:
let first = unwrap!(SomeEnum::First, item);
PS. I'm using this in my tests. It helps shorten the tests.
Upvotes: 6
Reputation: 22273
Given the following case:
fn main() {
let foo = Some(1);
let Some(bar) = foo;
}
error[E0005]: refutable pattern in local binding:
None
not covered
let Some(x) = y
introduces a pattern; let
and match
statements and function arguments are pattern-matching contexts, but since in this case the pattern doesn't cover the other possible case, it is not a valid pattern matching context.
The only contexts which the let Some(x) = y
statement is applicable to are the if let
expressions and while let
loops.
If you are sure (e.g. with an earlier assert!()
or if it is introduced "by hand") that a None
is not possible, you can just use unwrap()
.
Upvotes: 8