I am trying to use slice patterns on a slice of Strings. This does not work because Rust does not match the Strings of the slice with the &str literal. I could not find out how to convert the slice of Strings to a slice of &strs.
#![feature(slice_patterns)]
fn main() {
// A slice of strings.
let x = ["foo".to_owned(), "bar".to_owned()];
match x {
["foo", y] => println!("y is {}.", y),
_ => println!("I did not expect this."),
}
}
Playground
Technically, you don't have a slice of Strings (&[String]), you have an array of Strings ([String; 2]).
Let's take a look at a smaller case:
fn main() {
match "foo".to_owned() {
"foo" => println!("matched"),
_ => unreachable!(),
}
}
Here, we get the same error message:
error[E0308]: mismatched types
--> src/main.rs:3:9
|
3 | "foo" => println!("matched"),
| ^^^^^ expected struct `std::string::String`, found reference
|
= note: expected type `std::string::String`
found type `&'static str`
The fix in this case is to change the String into a &str, which is what the slice patterns understand:
let s = "foo".to_owned();
match s.as_str() {
"foo" => println!("matched"),
_ => unreachable!(),
}
See also:
So, how can we expand this to your example? The straight-forward thing is to do the same thing twice:
fn main() {
let x = ["foo".to_owned(), "bar".to_owned()];
match [x[0].as_str(), x[1].as_str()] {
["foo", y] => println!("y is {}.", y),
_ => unreachable!(),
}
}
However, this wouldn't work for the case of a slice (&[T]) because we only handle two values, not an arbitrary amount. In that case, we need to make a temporary Vec:
fn main() {
let x = ["foo".to_owned(), "bar".to_owned()];
let x2: Vec<_> = x.iter().map(|x| x.as_str()).collect();
match x2.as_slice() {
["foo", y] => println!("y is {}.", y),
_ => unreachable!(),
}
}
Note that you have to convert the Vec into a slice itself (x2.as_slice()) because slice patterns only understand slices.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With