Rust String vs str (&str) | Ownership, Slices, and API Design
이 글의 핵심
String vs &str in Rust: memory layout, borrowing, performance, and API design.
Introduction
“String or &str?” is the classic Rust beginner question. This article explains both and how to choose in APIs.
What you will learn
- Memory layout (heap vs slice)
- Ownership vs borrowing
- Conversion patterns
- Common lifetime mistakes
Table of contents
- Quick comparison
- Memory layout
- Ownership and borrowing
- Performance
- Conversions
- Practical guide
- Common mistakes
- Closing thoughts
1. Quick comparison
String | &str | |
|---|---|---|
| Kind | Owned UTF-8 | Borrowed slice |
| Storage | Heap + stack fat pointer | Stack pointer + len (often into static or heap) |
| Mutability | Can mutate buffer | View-only |
| Typical args | Move ownership | Borrow (&str) |
| Typical returns | Owned data | &str tied to input lifetime |
2. Memory layout
String is a growable UTF-8 buffer on the heap. &str is a slice—pointer + length—into UTF-8 bytes elsewhere (literal, String, etc.).
3. Ownership and borrowing
fn take_ownership(s: String) {
println!("{}", s);
} // drop
let s = String::from("hello");
take_ownership(s);
// println!("{}", s); // error: moved
fn borrow(s: &str) {
println!("{}", s);
}
let s = String::from("hello");
borrow(&s);
println!("{}", s); // OK
Prefer &str parameters unless you need to consume or store the string without a clear lifetime.
4. Performance
Cloning String allocates; copying &str copies two words. Hot paths should avoid unnecessary to_string().
5. Conversions
String→&str:&s,s.as_str(),&s[..]&str→String:to_string(),String::from,to_owned()
Build String only when you must own or mutate.
6. Practical guide
Parameters
fn print_message(msg: &str) {
println!("{}", msg);
}
Accepts literals, String slices, etc.
Struct fields
Usually String for owned data. &str fields need lifetimes:
struct UserRef<'a> {
name: &'a str,
}
Returns
Returning &str from local String is invalid—return String or Cow or borrow from input with correct lifetime.
7. Common mistakes
- Taking
Stringby value when&strsuffices - Extra
to_string()in hot paths - Returning
&strto dropped data
Closing thoughts
- Arguments:
&strby default Stringwhen you need ownership- Read-only views:
&str - If lifetimes get painful, prefer owning
String
FAQ
See frontmatter.
Related posts
- Rust ownership
- Rust borrowing
- Rust lifetimes
Keywords
Rust, String, str, slice, ownership, borrowing, lifetimes, performance, comparison