snippetrustModerate
How can I pattern match against an Option<String>?
Viewed 0 times
howstringoptionagainstcanpatternmatch
Problem
I can straight-forwardly match a
If I have an option type, it fails:
because the types don't match:
I can't do the
I have come up with so far is:
which works but is terrible for its verbosity.
In this case, my code is just an example. I do not control the creation of either the
Any other options?
String in Rust:let a = "hello".to_string();
match &a[..] {
"hello" => {
println!("Matches hello");
}
_ => panic!(),
}If I have an option type, it fails:
match Some(a) {
Some("hello") => {
println!("Matches some hello");
}
_ => panic!(),
}because the types don't match:
error[E0308]: mismatched types
--> src/main.rs:5:14
|
5 | Some("hello") => {
| ^^^^^^^ expected struct std::string::String, found reference
|
= note: expected type std::string::String
found type &'static str
I can't do the
[..] trick because we have an Option. The best thatI have come up with so far is:
match Some(a) {
Some(b) => match (&b[..]) {
"hello" => {
println!("Matches some, some hello");
}
_ => panic!(),
},
None => panic!(),
}which works but is terrible for its verbosity.
In this case, my code is just an example. I do not control the creation of either the
String or the Some(String) — so I can't change this type in reality as I could do in my example.Any other options?
Solution
It's a known limitation of Rust's patterns.
Method calls (including internal methods for operators like
On the other hand, the patterns are quite literal in their comparisons, and find that
There are two solutions:
-
Change
-
Use match guard:
See also:
Method calls (including internal methods for operators like
==) automatically call .deref() as needed, so String gets automagically turned into &str for comparisons with literals.On the other hand, the patterns are quite literal in their comparisons, and find that
String and &str are different.There are two solutions:
-
Change
Option to Option before matching on it: Some(a).as_deref(). The as_deref() is a combo of as_ref() that makes Option (preventing move), and deref()/as_str() then unambiguously references it as a &str.-
Use match guard:
match Some(a) { Some(ref s) if s == "hello" => … }. Some(ref s) matches any String, and captures it as s: &String, which you can then compare in the if guard which does the usual flexible coercions to make it work.See also:
- Converting from Option to Option
Context
Stack Overflow Q#48034119, score: 46
Revisions (0)
No revisions yet.