Rust String vs &str: what is the difference?
verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · rustc 1.98.1 (48a229cea 2026-09-01)updated
- tool
- Rust
- compares
- String vs &str
String owns its text: a heap buffer that can grow and is freed when the String is dropped. &str (a string slice) borrows text owned by someone else: a String, a string literal in the binary, or part of either. Store String in structs and return it from functions that build text; take &str as a parameter, because both &String and literals coerce to it.
Side by side
| String | &str | |
|---|---|---|
| Ownership | Owns the data, frees it on drop | Borrows data owned elsewhere |
| Mutability | Growable with push_str, push, insert | Read-only view |
| Layout (64-bit) | Pointer + capacity + length (24 bytes) | Pointer + length (16 bytes, a "fat pointer") |
| Literals | String::from("hi"), "hi".to_string() | "hi" has type &'static str |
| Function parameter | Takes ownership (caller gives the value up or clones) | Accepts &String, literals and slices |
| Conversion | &s or s.as_str() gives &str | to_string(), to_owned() or String::from() gives String |
In code
cat > main.rs <<'EOF'
fn shout(text: &str) -> String {
text.to_uppercase() // builds and returns an owned String
}
fn main() {
let mut owned: String = String::from("hello");
owned.push_str(", world"); // String can grow
let literal: &str = "rust"; // &'static str, lives in the binary
let slice: &str = &owned[0..5]; // borrowed view into the String
println!("{}", shout(&owned)); // &String coerces to &str
println!("{}", shout(literal));
println!("{}", shout(slice));
println!("size_of String = {}", std::mem::size_of::<String>());
println!("size_of &str = {}", std::mem::size_of::<&str>());
}
EOF
rustc main.rs && ./mainOutput
HELLO, WORLD RUST HELLO size_of String = 24 size_of &str = 16
Which one to use
- Parameters:
&str. A functionfn f(s: &str)accepts&String, literals and slices;fn f(s: String)forces callers to give up or clone their string. - Struct fields:
String, unless the struct is meant to borrow (then it needs a lifetime,struct Token<'a> { text: &'a str }). - Return values:
Stringwhen the function creates new text;&stronly when returning part of an input.
Sources
Related pages
errors · rustRust error[E0308]: mismatched typesRust E0308 means a value's type differs from what the compiler expected: a &str for a u16, String vs &str, or a missing return. Read expected/found and fix.errors · rustRust error[E0382]: borrow of moved valuerustc reports E0382 when a variable is used after its value moved to another binding or function. Borrow it with &, clone it, or reorder the code. Real output.cheat sheets · cargoCargo cheat sheet: build, run, test and manage Rust cratesCargo cheat sheet: new packages, check, build and run in debug or release, test, fmt, clippy, add and update dependencies, workspaces and flags for CI.