How to match a String against string literals?

I'm trying to figure out how to match a String in Rust.

I initially tried matching like this, but I figured out Rust cannot implicitly cast from std::string::String to &str.

fn main() {
    let stringthing = String::from("c");
    match stringthing {
        "a" => println!("0"),
        "b" => println!("1"),
        "c" => println!("2"),
    }
}

This has the error:

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
4 |         "a" => println!("0"),
  |         ^^^ expected struct `std::string::String`, found reference
  |
  = note: expected type `std::string::String`
             found type `&'static str`

I then tried to construct new String objects, as I could not find a function to cast a String to a &str.

fn main() {
    let stringthing = String::from("c");
    match stringthing {
        String::from("a") => println!("0"),
        String::from("b") => println!("1"),
        String::from("c") => println!("2"),
    }
}

This gave me the following error 3 times:

error[E0164]: `String::from` does not name a tuple variant or a tuple struct
 --> src/main.rs:4:9
  |
4 |         String::from("a") => return 0,
  |         ^^^^^^^^^^^^^^^^^ not a tuple variant or struct

How to actually match Strings in Rust?


UPDATE Use .as_str()

Reason .as_str() is more concise and enforces stricter type checking. The trait as_ref is implemented for multiple types and its behaviour could be changed for type String, leading to unexpected results. Similarly, if the input argument changes type, the compiler will not signal a problem when that type implements the trait as_ref.

The docs suggest to use as_str as well https://doc.rust-lang.org/std/string/struct.String.html, https://doc.rust-lang.org/std/primitive.str.html

Old answer:

as_slice is deprecated, you should now use the trait std::convert::AsRef instead:

match stringthing.as_ref() {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}

Note that you also have to explicitly handle the catch-all case.


You can do something like this:

match &stringthing[..] {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}

There's also an as_str method as of Rust 1.7.0:

match stringthing.as_str() {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}

You could also do

match &stringthing as &str {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}

See:

  • std::string::String
  • std::ops::Deref
  • Deref coercions