Rust: How to Compare String with String Literals (match)

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Rust Doesn't Let You Simply Compare String with "hello"?

\n\n

If you're just starting to learn Rust and have already encountered the need to match a variable of type String with some string literal like "hello" or "world", you've probably seen a strange compiler error. You write something like:

\n\n
let user_input = String::from("start");\nmatch user_input {\n    "start" => println!("Starting!"),\n    "stop"  => println!("Stopping!"),\n    _       => println!("Unknown command"),\n}\n
\n\n

And the compiler outputs something like: "expected struct `String`, found `&str`". Sound familiar?

\n\n

On Stack Overflow, the question "How to match a String against string literals?" has thousands of views — it's a real pain point for beginners. In this article, we'll break down why this happens and show three simple ways to solve the problem. You'll learn how Rust's ownership and borrowing system works in practice and stop being afraid of compiler errors.

\n\n

The Nature of the Conflict: String vs &str

\n\n

To understand the problem, you need to recall the basics. Rust has two main types for working with text:

\n\n
    \n
  • String — an owned string stored on the heap. It can be modified, grow, and shrink. Example: let s = String::from("hello");
  • \n
  • &str — a string slice. It is a reference to part of a string (or to a string literal stored directly in the program's binary). Example: "hello" is exactly &'static str.
  • \n
\n\n

When you write match user_input { "start" => ... }, you are trying to compare a String with a &str. The compiler says: "I don't know how to match them directly; the types are different!". And this is good — Rust protects you from implicit conversions that could lead to performance loss or hidden bugs.

\n\n

But what to do then? There are three simple and elegant solutions.

\n\n

Solution 1: Borrowing via as_str()

\n\n

The most direct and understandable way is to get a string slice (&str) from a String using the as_str() method. This method returns a reference to the string's content without copying it. It looks like this:

\n\n
fn main() {\n    let command = String::from("start");\n\n    match command.as_str() {\n        "start" => println!("System starting..."),\n        "stop"  => println!("Stopping..."),\n        "pause" => println!("Pausing..."),\n        _       => println!("Unknown command: {}", command),\n    }\n}\n
\n\n

Why does this work? as_str() returns a &str, which can now be compared with literals. Rust sees that both operands are &str, and pattern matching works perfectly.

\n\n

Pros: simplicity, readability, zero overhead (borrowing, not copying).

\n\n

Cons: you need to remember to call the method. But that's a minor detail.

\n\n

Solution 2: Comparison in an if Condition

\n\n

If you don't need the full power of match, you can use regular if with the eq() method or the == operator. Rust can compare String and &str via the PartialEq trait, which is implemented for this pair of types.

\n\n
fn main() {\n    let user_input = String::from("admin");\n\n    if user_input == "admin" {\n        println!("Access granted!");\n    } else if user_input == "guest" {\n        println!("Guest access");\n    } else {\n        println!("Invalid login");\n    }\n}\n
\n\n

This works because the compiler automatically coerces String to &str during comparison. But in match, such coercion does not exist — it requires an exact

Blogs

Book Recommendations