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?

2

6 Answers

UPDATE:Use .as_str() like this to convert the String to an &str:

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

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 ,

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.

6

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!"),
}
0

You could also do

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

See:

2

Editor's note: This answer pertains to an version of Rust before 1.0 and does not work in Rust 1.0

You can match on a string slice.

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

You can try:

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

You can convert the String into &str by doing this:

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like