String vs str in Rust: Why Beginners Get Confused and How to Understand It Once and For All
\n\nIf you're just starting to learn Rust, you've probably already encountered a situation: the compiler complains, you try to pass a String where &str is expected, or vice versa. Sound familiar? This is one of the most popular questions on Stack Overflow (thousands of views!), and for good reason — the topic is truly fundamental for understanding memory management in Rust.
In this article, we'll break down the differences between String and &str, when to use each type, and how to avoid typical mistakes. Let's go!
Short Answer for Those in a Hurry
\n\nIf you need it right now — remember the main points:
\n\n- \n
Stringis an owning, mutable, dynamic data type that is stored on the heap. \n&stris an immutable string slice that references data owned by someone else. It is most commonly encountered as&str. \n
Now let's dig deeper.
\n\nWhat is String in Rust?
\n\nString is a type that owns its data. When you create a String, memory for it is allocated on the heap, and the string can grow, shrink, or be modified.
let mut s = String::from("Hello");\ns.push_str(", world!");\nprintln!("{}", s); // Output: Hello, world!\n\nHere, s is the owner of the string. When s goes out of scope, the memory is automatically freed (thanks to RAII — Resource Acquisition Is Initialization).
Key Characteristics of String:
\n- \n
- Owns the data (owning type) \n
- Mutable \n
- Stored on the heap \n
- Can be created from a string literal:
String::from("text")\n - Supports concatenation, insertion, and deletion of characters \n
What is &str in Rust?
\n\n&str (pronounced "string slice") is a reference to a sequence of UTF-8 characters that belongs to someone else. By itself, &str is simply a pointer to the data and a length.
let greeting: &str = "Hello";\nprintln!("{}", greeting);\n\nIn this example, greeting is a reference to a string literal that is stored directly in the program's binary file (in the read-only memory segment). greeting does not own this data — it just looks at it.
Key Characteristics of &str:
\n- \n
- Does not own the data (borrowed type) \n
- Immutable \n
- Stored either in the binary (string literals) or on the heap (as a slice from a
String) \n - Lightweight — consists of two fields: pointer + length (16 bytes on a 64-bit system) \n
- Ideal for passing to functions when you don't need to modify the string \n
Key Differences Between String and &str (Table)
\n\nLet's summarize everything in a clear table:
\n\n| Characteristic | \nString | \n&str | \n
|---|---|---|
| Ownership | \nOwns the data | \nBorrows the data | \n
| Mutability | \nYes (mut) | \nNo | \n
| Storage Location | \nHeap | \nHeap, stack, or binary | \n
| Size on Stack | \n24 bytes (ptr + len + cap) | \n16 bytes (ptr + len) | \n
| Creation | \nString::from("...") | \n"..." or &s[..] | \n
| Primary Use | \nWhen you need to modify or own
BlogsBook RecommendationsRead also |