Reputation: 723
If I have a enum that imitates an option type, it can either contain some value, or nothing:
enum option {
some(u8),
none,
}
Then I can pattern match it like this:
let x = option::some(8);
match x {
some => println!("some"),
none => println!("none"),
}
But what if I want to pattern match the value inside the some? Intuitively, I think it would be something like so:
match x {
some(x) => println!("{}", x),
none => println!("none"),
}
But Rust has no idea what this is.
I also try to see if the some
itself is the u8
value:
match x {
some => println!("{}", some),
none => println!("none"),
}
This also does not work. How do I get the value inside the enum?
Upvotes: 2
Views: 1985
Reputation: 42612
Completment to at54321's answer:
Then I can pattern match it like this:
let x = option::some(8); match x { some => println!("some"), none => println!("none"), }
That does not actually work, it will always match the first branch (always print some
), and if you read the compiler's warning it'll tell you that:
warning: unreachable pattern
--> src/main.rs:11:5
|
10 | some => println!("some"),
| ---- matches any value
11 | none => println!("none"),
| ^^^^ unreachable pattern
|
= note: `#[warn(unreachable_patterns)]` on by default
warning: unused variable: `some`
--> src/main.rs:10:5
|
10 | some => println!("some"),
| ^^^^ help: if this is intentional, prefix it with an underscore: `_some`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `none`
--> src/main.rs:11:5
|
11 | none => println!("none"),
| ^^^^ help: if this is intentional, prefix it with an underscore: `_none`
So it tells you that none
is not reachable (because the first branch is a catchall), and it hints that some
and none
are new bindings, not enum variants.
But what if I want to pattern match the value inside the some? Intuitively, I think it would be something like so:
match x { some(x) => println!("{}", x), none => println!("none"), }
If, again, you read the error message, the compiler gives you the solution (though the why is not clear):
error[E0531]: cannot find tuple struct or tuple variant `some` in this scope
--> src/main.rs:10:5
|
10 | some(x) => println!("some"),
| ^^^^
|
help: a tuple variant with a similar name exists
|
10 | Some(x) => println!("some"),
| ~~~~
help: consider importing this tuple variant
|
1 | use crate::option::some;
|
The issue here is that Rust enums are scoped, which you can see from... the creation of the variant. If you use option::some
when creating a value, why would the option::
bit be optional when matching it? And the answer's it's not (and in fact it's generally a good idea to include it, in order to avoid risks of collision / ambiguity between matching a variant and creating a new one).
It's also not entirely clear why you're creating an option type when there's one in the standard library, I will say.
Upvotes: 1
Reputation: 11866
This should work:
let x = option::some(8);
match x {
option::some(x) => println!("{}", x),
option::none => println!("none"),
}
But keep in mind this all-lower-case naming is against the standard Rust naming conventions. Your code will look much better like this:
enum Option {
Some(u8),
None
}
pub fn main() {
let x = Option::Some(8);
match x {
Option::Some(x) => println!("{}", x),
Option::None => println!("none"),
}
}
You might see that note as nitpicking, but as you add more and more code, that will become a much bigger issue. So it's good to build the right habits from the beginning.
Upvotes: 8