Rust String vs str (&str) | Ownership, Slices, and API Design

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

  1. Quick comparison
  2. Memory layout
  3. Ownership and borrowing
  4. Performance
  5. Conversions
  6. Practical guide
  7. Common mistakes
  8. Closing thoughts

1. Quick comparison

String&str
KindOwned UTF-8Borrowed slice
StorageHeap + stack fat pointerStack pointer + len (often into static or heap)
MutabilityCan mutate bufferView-only
Typical argsMove ownershipBorrow (&str)
Typical returnsOwned 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[..]
  • &strString: 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 String by value when &str suffices
  • Extra to_string() in hot paths
  • Returning &str to dropped data

Closing thoughts

  1. Arguments: &str by default
  2. String when you need ownership
  3. Read-only views: &str
  4. If lifetimes get painful, prefer owning String

FAQ

See frontmatter.


  • Rust ownership
  • Rust borrowing
  • Rust lifetimes

Keywords

Rust, String, str, slice, ownership, borrowing, lifetimes, performance, comparison