Mysterious Apostrophes in Rust: What Hides Behind Quoted Identifiers?

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

What Hides Behind a Single Quote? Getting to Know Lifetimes in Rust



If you've ever opened Rust code and seen strange constructs like &'a str or fn foo<'a>(), you've probably wondered: "What are those apostrophes?" You're not alone — this question has gathered thousands of views on Stack Overflow and has become a real headache for beginners.



Today we'll finally figure out these mysterious symbols. Spoiler: behind the quotes hides one of the most powerful concepts in Rust — lifetimes. And yes, it's not as scary as it seems!



In this article, I'll talk not only about the syntax but also about how to correctly read and use identifiers with apostrophes. Let's go!



Identifiers with Apostrophes: Not Just Decoration



In Rust, identifiers starting with a single quote (e.g., 'a, 'static, 'b) are lifetime annotations. They don't affect how long a variable lives, but rather tell the compiler about the relationships between the lifetimes of different references.



Imagine you're a detective, and the Rust compiler is your assistant. You say: "These two references must live equally long," and you mark them with the label 'a. The compiler checks whether you're violating this rule. If you do, you get an error at compile time, not at runtime.



Why Do They Look Like This?



The apostrophe syntax was chosen for a reason. In Rust, the apostrophe is used to denote labels — these are essentially "names" for time intervals. This approach is also found in other languages, but in Rust it has become a key element of the memory safety system.



Here are a few examples where you'll encounter these labels:



  • fn longest<'a>(x: &'a str, y: &'a str) -> &'a str — a function that returns a reference that lives no longer than both arguments.
  • struct Book<'a> { title: &'a str } — a structure containing a reference with a lifetime.
  • &'static str — a reference to a static string that lives for the entire program duration.


How to Read and Understand Lifetimes?



Let's break down a few real code examples. They will help you stop fearing apostrophes and start using them.



Example 1: Function with One Lifetime



Suppose we write a function that returns the longer of two strings:



fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {    if x.len() > y.len() { x } else { y }}

fn main() { let string1 = String::from("hello"); let result; { let string2 = String::from("world"); result = longest(&string1, &string2); } // println!("{}", result); // Compilation error!}


What's happening here? We tell the compiler: "The result will live no longer than x and y combined." When string2 goes out of scope, result becomes invalid. The compiler sees this and doesn't let us shoot ourselves in the foot.



Example 2: Structure with a Reference



Beginners often try to store references in structures and get errors. The solution is to explicitly specify the lifetime:



#[derive(Debug)]struct Book<'a> {    title: &'a str,    author: &'a str,}

fn main() { let title = String::from("The Rust Programming Language"); let author = String::from("Steve Klabnik"); let book = Book { title: &title, author: &author, }; println!("{:?}", book);}


Here 'a means that title and author must live at least as long as the Book structure itself. If you try to delete

Blogs

Book Recommendations