4

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

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Pyfisch
  • 1,752
  • 1
  • 17
  • 29

1 Answers1

2

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Is there a difference between creating a string slice e.g. `&x[..]` and doing an explicit reborrow e.h. `&*x`? – chad Nov 22 '15 at 21:46
  • @chad I don't *think* there is a difference, but I am not sure. That sounds like a straight-forward thing you could [ask a new question for](http://stackoverflow.com/questions/ask) and get a more reliable answer for, and maybe some points. :-) – Shepmaster Nov 22 '15 at 21:50
  • This is the question: http://stackoverflow.com/questions/33860750/is-there-a-difference-between-slicing-and-an-explicit-reborrow-when-converting-s – Pyfisch Nov 23 '15 at 11:43