How to get &'static str from String in Rust: a complete guide with examples

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

Introduction: why is this even a problem?

\n

If you've ever written anything in Rust more complex than "Hello, World!", you've probably encountered a situation where the compiler literally yells at you: "expected &'static str, but found String". Sound familiar? This is one of the most popular questions on Stack Overflow (tens of thousands of views), and for good reason.

\n

The thing is, String and &'static str are two different beasts. String is an owning type that can grow and change at runtime. And &'static str is a reference to a string slice that lives for the entire program. It's like comparing a suitcase with things (String) to a permanently fixed shelf (&'static str).

\n

In this tutorial, we'll cover all legal ways to turn a String into &'static str, from simple to advanced. And yes, I'll show you how not to shoot yourself in the foot in the process.

\n\n

What exactly is &'static str?

\n

Before we write code, let's understand the theory. &'static str is a reference to a string that is guaranteed to live for the entire duration of the program. Such strings are usually hardcoded into the binary:

\n
let hello: &'static str = "Hello, world!"; // Lives forever\n
\n

But what if the string is created dynamically? For example, read from a file or coming from the network? That's where the fun begins.

\n\n

Method #1: The simplest — memory leak (yes, it's legal)

\n

Yes, you heard that right. Rust has a deliberate memory leak via the Box::leak function. This is not a bug, it's a feature! You literally tell the compiler: "Forget about this memory, it's mine forever."

\n
use std::boxed::Box;\n\nfn string_to_static_str(s: String) -> &'static str {\n    // Convert String to Box<str>, then "forget" about it\n    let boxed_str: Box<str> = s.into_boxed_str();\n    // Now this string will live forever\n    Box::leak(boxed_str)\n}\n\nfn main() {\n    let dynamic_string = String::from("I was born dynamically!");\n    let static_ref: &'static str = string_to_static_str(dynamic_string);\n    println!("{}", static_ref);\n    // The memory will never be freed\n}\n
\n

Pros: Simple, efficient, no external crates required.
\nCons: You permanently lose control over the memory. If you call this in a loop — hello, OOM (Out of Memory).

\n\n

When is this appropriate?

\n
    \n
  • When you know for sure that the string is needed for the entire lifetime of the program (e.g., configuration loaded once at startup).
  • \n
  • In embedded systems where there is no heap and everything is static.
  • \n
\n\n

Method #2: Lazy Static — for the lazy and the smart

\n

The lazy_static crate is a Rust classic. It allows you to create a static variable that is initialized only on first access. Perfect for configs and global data.

\n
// Add to Cargo.toml: lazy_static = "1.4"\nuse lazy_static::lazy_static;\n\nlazy_static! {\n    static ref MY_STRING: String = {\n        // Let's say we read a string from a file\n        String::from("Loaded lazily!")\n    };\n}\n\nfn get_static_str() -> &'static str {\n    // lazy_static automatically gives &'static str\n    &MY_STRING\n}\n\nfn main() {\n    println!("{}", get_static_str());\n}\n
\n

Pros: \n

    \n
  • Safe (no memory leak).
  • \n
  • Lazy initialization — the string is created only when needed.
  • \n
  • Works with any types, not just strings.
  • \n
\nCons: \n
    \n
  • Dependency on an external crate.
  • \n
  • Can be overkill for simple cases.
  • \n
\n

\n\n

Method #3: OnceCell and OnceLock — a modern alternative

\n

Starting with Rust 1.70, the standa

Blogs

Book Recommendations