<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<inputtype="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>A lifetime means "how long the variable lives". You only need to think about lifetimes with references. This is because references can't live longer than the object they come from. For example, this function does not work:</p>
let my_string = String::from("I am a string");
&my_string // ⚠️
}
fn main() {}
</code></pre></pre>
<p>The problem is that <code>my_string</code> only lives inside <code>returns_reference</code>. We try to return <code>&my_string</code>, but <code>&my_string</code> can't exist without <code>my_string</code>. So the compiler says no.</p>
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
6 | fn returns_str() ->&'static str {
| ^^^^^^^^
</code></pre>
<p><code>missing lifetime specifier</code> means that we need to add a <code>'</code> with the lifetime. Then it says that it <code>contains a borrowed value, but there is no value for it to be borrowed from</code>. That means that <code>I am a str</code> isn't borrowed from anything. It says <code>consider using the 'static lifetime</code> by writing <code>&'static str</code>. So it thinks we should try saying that this is a string literal.</p>
let my_string = String::from("I am a string");
"I am a str"
}
fn main() {
let my_str = returns_str();
println!("{}", my_str);
}
</code></pre></pre>
<p>That's because we returned a <code>&str</code> with a lifetime of <code>static</code>. Meanwhile, <code>my_string</code> can only be returned as a <code>String</code>: we can't return a reference to it because it is going to die in the next line.</p>
<p>So now <code>fn returns_str() ->&'static str</code> tells Rust: "don't worry, we will only return a string literal". String literals live for the whole program, so Rust is happy. You'll notice that this is similar to generics. When we tell the compiler something like <code><T: Display></code>, we promise that we will only use inputs with <code>Display</code>. Lifetimes are similar: we are not changing any variable lifetimes. We are just telling the compiler what the lifetimes of the inputs will be.</p>
<p>But <code>'static</code> is not the only lifetime. Actually, every variable has a lifetime, but usually we don't have to write it. The compiler is pretty smart and can usually figure out for itself. We only have to write the lifetime when the compiler doesn't know.</p>
<p>Here is an example of another lifetime. Imagine we want to create a <code>City</code> struct and give it a <code>&str</code> for the name. We might want to do that because it gives faster performance than with <code>String</code>. So we write it like this, but it won't work yet:</p>
help: consider introducing a named lifetime parameter
|
2 | struct City<'a> {
3 | name: &'a str,
|
</code></pre>
<p>Rust needs a lifetime for <code>&str</code> because <code>&str</code> is a reference. What happens when the value that <code>name</code> points to is dropped? That would be unsafe.</p>
<p>What about <code>'static</code>, will that work? We used it before. Let's try:</p>
name: &'static str, // change &str to &'static str
date_founded: u32,
}
fn main() {
let my_city = City {
name: "Ichinomiya",
date_founded: 1921,
};
println!("{} was founded in {}", my_city.name, my_city.date_founded);
}
</code></pre></pre>
<p>Okay, that works. And maybe this is what you wanted for the struct. However, note that we can only take "string literals", so not references to something else. So this will not work:</p>
name: &'static str, // must live for the whole program
date_founded: u32,
}
fn main() {
let city_names = vec!["Ichinomiya".to_string(), "Kurume".to_string()]; // city_names does not live for the whole program
let my_city = City {
name: &city_names[0], // ⚠️ This is a &str, but not a &'static str. It is a reference to a value inside city_names
date_founded: 1921,
};
println!("{} was founded in {}", my_city.name, my_city.date_founded);
}
</code></pre></pre>
<p>The compiler says:</p>
<pre><codeclass="language-text">error[E0597]: `city_names` does not live long enough
--> src\main.rs:12:16
|
12 | name: &city_names[0],
| ^^^^^^^^^^
| |
| borrowed value does not live long enough
| requires that `city_names` is borrowed for `'static`
...
18 | }
| - `city_names` dropped here while still borrowed
</code></pre>
<p>This is important to understand, because the reference we gave it actually lives long enough. But we promised that we would only give it a <code>&'static str</code>, and that is the problem.</p>
<p>So now we will try what the compiler suggested before. It said to try writing <code>struct City<'a></code> and <code>name: &'a str</code>. This means that it will only take a reference for <code>name</code> if it lives as long as <code>City</code>.</p>
name: &'a str, // and name also has lifetime 'a.
date_founded: u32,
}
fn main() {
let city_names = vec!["Ichinomiya".to_string(), "Kurume".to_string()];
let my_city = City {
name: &city_names[0],
date_founded: 1921,
};
println!("{} was founded in {}", my_city.name, my_city.date_founded);
}
</code></pre></pre>
<p>Also remember that you can write anything instead of <code>'a</code> if you want. This is also similar to generics where we write <code>T</code> and <code>U</code> but can actually write anything.</p>
struct City<'city> { // The lifetime is now called 'city
name: &'city str, // and name has the 'city lifetime
date_founded: u32,
}
fn main() {}
</code></pre></pre>
<p>So usually you will write <code>'a, 'b, 'c</code> etc. because it is quick and the usual way to write. But you can always change it if you want. One good tip is that changing the lifetime to a "human-readable" name can help you read code if it is very complicated.</p>
<p>Let's look at the comparison to traits for generics again. For example:</p>
<p>It means "please only take an input for <code>name</code> if it lives at least as long as <code>City</code>".
It does not mean: "I will make the input for <code>name</code> live as long as <code>City</code>".</p>
<p>Now we can learn about <code><'_></code> that we saw before. This is called the "anonymous lifetime" and is an indicator that references are being used. Rust will suggest it to you when you are implementing structs, for example. Here is one struct that almost works, but not yet:</p>
println!("{} has {} hit points left!", self.name, self.hit_points);
}
}
fn main() {}
</code></pre></pre>
<p>So we did what we needed to do for the <code>struct</code>: first we said that <code>name</code> comes from a <code>&str</code>. That means we need a lifetime, so we gave it <code><'a></code>. Then we had to do the same for the <code>struct</code> to show that they are at least as long as this lifetime. But then Rust tells us to do this:</p>
<pre><codeclass="language-text">error[E0726]: implicit elided lifetime not allowed here
--> src\main.rs:6:6
|
6 | impl Adventurer {
| ^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
</code></pre>
<p>It wants us to add that anonymous lifetime to show that there is a reference being used. So if we write that, it will be happy:</p>
println!("{} has {} hit points left!", self.name, self.hit_points);
}
}
fn main() {}
</code></pre></pre>
<p>This lifetime was made so that you don't always have to write things like <code>impl<'a> Adventurer<'a></code>, because the struct already shows the lifetime.</p>
<p>Lifetimes can be difficult in Rust, but here are some tips to avoid getting too stressed about them:</p>
<ul>
<li>You can stay with owned types, use clones etc. if you want to avoid them for the time being.</li>
<li>Much of the time, when the compiler wants a lifetime you will just end up writing <'a> here and there and then it will work. It's just a way of saying "don't worry, I won't give you anything that doesn't live long enough".</li>
<li>You can explore lifetimes just a bit at a time. Write some code with owned values, then make one a reference. The compiler will start to complain, but also give some suggestions. And if it gets too complicated, you can undo it and try again next time.</li>
</ul>
<p>Let's do this with our code and see what the compiler says. First we'll go back and take the lifetimes out, and also implement <code>Display</code>. <code>Display</code> will just print the <code>Adventurer</code>'s name.</p>
write!(f, "{} has {} hit points.", self.name, self.hit_points)
}
}
fn main() {
let mut billy = Adventurer {
name: "Billy",
hit_points: 100_000,
};
println!("{}", billy);
billy.take_damage();
}
</code></pre></pre>
<p>This prints:</p>
<pre><codeclass="language-text">Billy has 100000 hit points.
Billy has 99980 hit points left!
</code></pre>
<p>So you can see that lifetimes are often just the compiler wanting to make sure. And it is usually smart enough to almost guess at what lifetimes you want, and just needs you to tell it so it can be certain.</p>