I wrote this snippet:
let my_option: Option<()> = None;
if my_option.is_some() {
my_option.unwrap();
}
Clippy is telling me to use:
if let Some(..) = my_option {
my_option.unwrap();
}
What does Some(..)
mean? Is it just dropping the value similar to how using _
would in some cases? And where can I find more information about when and where I can use the ..
?
I think the Clippy warning is slightly misleading. Let's first look at the full warning message:
warning: called `unwrap` on `my_option` after checking its variant with `is_some`
--> src/main.rs:4:9
|
3 | if my_option.is_some() {
| ---------------------- help: try: `if let Some(..) = my_option`
4 | my_option.unwrap();
| ^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(clippy::unnecessary_unwrap)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
Clippy is complaining about the use of unwrap()
after checking with is_some()
. If you use is_some()
only or unwrap()
only, Clippy won't complain. It's only unwrapping after checking that's considered unidiomatic, since it can be easier done using if let
.
I believe the reason for Clippy to suggest if let Some(..) = my_option
is that the code does not track how the inner value is used later, so the suggestion needs to be somehow generic. In practice, you would hardly ever literally write ..
here, but instead write something like
if let Some(value) = my_option
to bind the inner value to a variable. Also note that if let Some(..) = my_option
does not consume the option, while if let Some(value) = my_option
does (if the inner type is not Copy
).
In summary:
Some
, but are not interested in the contained value, you should use if my_option.is_some()
.Some
, and you want to extract the inner value, use my_option.unwrap()
without any enclosing if
.Some
, and you want to extract the inner value only in case it is, use if let Some(value) = my_value
.