Question
In Rust, how can you correctly match a String value against string literals inside a match expression?
For example, this code does not compile:
fn main() {
let stringthing = String::from("c");
match stringthing {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
}
}
It produces a type mismatch error because the match expression is working with a String, but the match arms use string literals of type &'static str.
Trying to match with String::from(...) patterns also does not work:
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 fails because String::from(...) is a function call, not a valid match pattern.
What is the correct way to match a String against string literals in Rust?
Short Answer
By the end of this page, you will understand why String and &str are different types in Rust, why string literals work differently in match, and how to correctly match a String by converting or borrowing it as &str. You will also see common patterns used in real Rust code.
Concept
In Rust, String and &str are related but different types.
Stringis an owned, growable string stored on the heap.&stris a borrowed string slice, which is a view into string data.- String literals like
"hello"have type&'static str.
This matters in match because match patterns must match the type of the value being matched.
When you write:
match stringthing {
"a" => println!("0"),
// ...
}
Rust expects each pattern to match a String, because stringthing is a String. But "a" is a &str, not a String, so the types do not match.
Your second attempt fails for a different reason: patterns in match are not general expressions. creates a value at runtime, but match patterns must follow pattern syntax, not arbitrary function calls.
Mental Model
Think of String as a full book you own, and &str as a page reference pointing to text inside that book.
- A
Stringowns the text. - A
&strborrows access to some or all of that text. - A string literal like
"a"is already a borrowed piece of text.
match wants the thing on the left and the patterns on the right to speak the same language.
If you try to compare:
- owned book (
String) - page reference (
&str)
Rust says: these are not the same type.
So the fix is simple: borrow the String as &str, then match it against string literals, which are also &str.
Syntax and Examples
The most common way to match a String against literals is to convert it to &str first.
Recommended syntax
fn main() {
let stringthing = String::from("c");
match stringthing.as_str() {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("other"),
}
}
Why this works
stringthing.as_str()gives a&str"a","b", and"c"are also&str- Now the matched value and the patterns have compatible types
Another valid form
Step by Step Execution
Consider this example:
fn main() {
let stringthing = String::from("b");
match stringthing.as_str() {
"a" => println!("0"),
"b" => println!("1"),
"c" => println!("2"),
_ => println!("other"),
}
}
Here is what happens step by step:
String::from("b")creates an ownedStringcontainingb.stringthing.as_str()creates a borrowed&strview into that string.matchcompares that&stragainst each pattern in order."a"does not match."b"matches.
Real World Use Cases
Matching strings is common in Rust programs whenever text input determines behavior.
Command-line tools
fn handle_command(command: String) {
match command.as_str() {
"start" => println!("Starting..."),
"stop" => println!("Stopping..."),
"status" => println!("Checking status..."),
_ => println!("Unknown command"),
}
}
Parsing user input
A menu selection entered as text can be matched against known options.
API routing or action selection
A small internal service might use string-based action names like "create", "update", or "delete".
Configuration values
fn set_mode(mode: String) {
match mode.as_str() {
"debug" => (),
=> (),
_ => (),
}
}
Real Codebase Usage
In real Rust projects, developers usually avoid taking ownership unless needed. That means they often work with &str for matching.
Common pattern: accept &str in functions
fn handle_status(status: &str) {
match status {
"ok" => println!("All good"),
"error" => println!("Something went wrong"),
_ => println!("Unknown status"),
}
}
Then you can call it with either a string literal or a String:
fn main() {
let s = String::from("ok");
handle_status(&s);
handle_status("error");
}
Guard clauses and validation
fn parse_role(role: &str) {
role {
=> (),
=> (),
=> (),
_ => (),
}
}
Common Mistakes
1. Matching a String directly against string literals
This does not work:
let value = String::from("a");
match value {
"a" => println!("A"),
_ => println!("Other"),
}
Why
valueis aString"a"is a&strmatchpatterns require compatible types
Fix
match value.as_str() {
"a" => println!("A"),
_ => println!("Other"),
}
2. Using function calls as patterns
This is invalid:
value {
::() => (),
_ => (),
}
Comparisons
String vs &str
| Type | Ownership | Growable | Typical use |
|---|---|---|---|
String | Owned | Yes | Store and build text |
&str | Borrowed | No | Read-only view of text |
match vs if/else for strings
| Approach | Best for | Example |
|---|---|---|
match | Many exact known values |
Cheat Sheet
Quick rules
Stringis owned text&stris a borrowed string slice- String literals like
"abc"are&str - In
match, patterns must match the value's type - To match a
Stringagainst literals, convert it to&str
Most common solution
match my_string.as_str() {
"a" => println!("A"),
"b" => println!("B"),
_ => println!("Other"),
}
Alternative
match &my_string[..] {
"a" => println!("A"),
_ => println!("Other"),
}
Not valid
match my_string {
=> (),
_ => (),
}
FAQ
Why can't I match a String directly with "text" in Rust?
Because String and &str are different types. A string literal like "text" is a &str, so you need to borrow the String as &str first.
What is the easiest way to convert String to &str?
Use .as_str():
my_string.as_str()
Why does String::from("a") not work in a match arm?
Because match arms use patterns, not arbitrary expressions. String::from("a") is a function call expression.
Should I use match or if for strings in Rust?
Use match for multiple exact cases. Use if for one simple comparison or more complex boolean conditions.
Mini Project
Description
Build a small command interpreter that reads a command stored in a String and responds based on its value. This demonstrates the practical way to match String input against string literals by borrowing it as &str first.
Goal
Create a Rust program that matches String commands like start, stop, and status and prints the correct response.
Requirements
- Store a command in a
String - Use
matchto compare the command against string literals - Handle at least three known commands
- Include a fallback case for unknown commands
- Keep the original
Stringusable after the match
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Default Function Arguments in Rust: What to Use Instead
Learn how Rust handles default function arguments, why they are not supported, and practical patterns to achieve similar behavior.
Fixing Rust "linker 'cc' not found" on Debian in WSL
Learn why Rust shows "linker 'cc' not found" on Debian in WSL and how to fix it by installing the required C build tools.