The main aim of lifetimes is to prevent *dangling references*, which cause a
program to reference data other than the data it’s intended to reference.
-Consider the program in Listing 10-17, which has an outer scope and an inner
+Consider the program in Listing 10-16, which has an outer scope and an inner
scope.
```rust,ignore,does_not_compile
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/main.rs}}
```
-<span class="caption">Listing 10-17: An attempt to use a reference whose value
+<span class="caption">Listing 10-16: An attempt to use a reference whose value
has gone out of scope</span>
-> Note: The examples in Listings 10-17, 10-18, and 10-24 declare variables
+> Note: The examples in Listings 10-16, 10-17, and 10-23 declare variables
> without giving them an initial value, so the variable name exists in the
> outer scope. At first glance, this might appear to be in conflict with Rust’s
> having no null values. However, if we try to use a variable before giving it
try to use it. Here is the error message:
```console
-{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt}}
+{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt}}
```
The variable `x` doesn’t “live long enough.” The reason is that `x` will be out
### The Borrow Checker
The Rust compiler has a *borrow checker* that compares scopes to determine
-whether all borrows are valid. Listing 10-18 shows the same code as Listing
-10-17 but with annotations showing the lifetimes of the variables.
+whether all borrows are valid. Listing 10-17 shows the same code as Listing
+10-16 but with annotations showing the lifetimes of the variables.
```rust,ignore,does_not_compile
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs}}
```
-<span class="caption">Listing 10-18: Annotations of the lifetimes of `r` and
+<span class="caption">Listing 10-17: Annotations of the lifetimes of `r` and
`x`, named `'a` and `'b`, respectively</span>
Here, we’ve annotated the lifetime of `r` with `'a` and the lifetime of `x`
with a lifetime of `'b`. The program is rejected because `'b` is shorter than
`'a`: the subject of the reference doesn’t live as long as the reference.
-Listing 10-19 fixes the code so it doesn’t have a dangling reference and
+Listing 10-18 fixes the code so it doesn’t have a dangling reference and
compiles without any errors.
```rust
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs}}
```
-<span class="caption">Listing 10-19: A valid reference because the data has a
+<span class="caption">Listing 10-18: A valid reference because the data has a
longer lifetime than the reference</span>
Here, `x` has the lifetime `'b`, which in this case is larger than `'a`. This
We’ll write a function that returns the longer of two string slices. This
function will take two string slices and return a single string slice. After
-we’ve implemented the `longest` function, the code in Listing 10-20 should
+we’ve implemented the `longest` function, the code in Listing 10-19 should
print `The longest string is abcd`.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs}}
```
-<span class="caption">Listing 10-20: A `main` function that calls the `longest`
+<span class="caption">Listing 10-19: A `main` function that calls the `longest`
function to find the longer of two string slices</span>
Note that we want the function to take string slices, which are references,
rather than strings, because we don’t want the `longest` function to take
ownership of its parameters. Refer to the [“String Slices as
Parameters”][string-slices-as-parameters]<!-- ignore --> section in Chapter 4
-for more discussion about why the parameters we use in Listing 10-20 are the
+for more discussion about why the parameters we use in Listing 10-19 are the
ones we want.
-If we try to implement the `longest` function as shown in Listing 10-21, it
+If we try to implement the `longest` function as shown in Listing 10-20, it
won’t compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore,does_not_compile
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs:here}}
```
-<span class="caption">Listing 10-21: An implementation of the `longest`
+<span class="caption">Listing 10-20: An implementation of the `longest`
function that returns the longer of two string slices but does not yet
compile</span>
Instead, we get the following error that talks about lifetimes:
```console
-{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt}}
+{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/output.txt}}
```
The help text reveals that the return type needs a generic lifetime parameter
be passed into this function, so we don’t know whether the `if` case or the
`else` case will execute. We also don’t know the concrete lifetimes of the
references that will be passed in, so we can’t look at the scopes as we did in
-Listings 10-18 and 10-19 to determine whether the reference we return will
+Listings 10-17 and 10-18 to determine whether the reference we return will
always be valid. The borrow checker can’t determine this either, because it
doesn’t know how the lifetimes of `x` and `y` relate to the lifetime of the
return value. To fix this error, we’ll add generic lifetime parameters that
One lifetime annotation by itself doesn’t have much meaning, because the
annotations are meant to tell Rust how generic lifetime parameters of multiple
-references relate to each other. For example, let’s say we have a function with
-the parameter `first` that is a reference to an `i32` with lifetime `'a`. The
-function also has another parameter named `second` that is another reference to
-an `i32` that also has the lifetime `'a`. The lifetime annotations indicate
-that the references `first` and `second` must both live as long as that generic
-lifetime.
+references relate to each other. Let’s examine how the lifetime annotations
+relate to each other in the context of the `longest` function.
### Lifetime Annotations in Function Signatures
-Now let’s examine lifetime annotations in the context of the `longest`
-function. As with generic type parameters, we need to declare generic lifetime
-parameters inside angle brackets between the function name and the parameter
-list. We want the signature to express the following constraint: the returned
+To use lifetime annotations in function signatures, we need to declare the
+generic *lifetime* parameters inside angle brackets between the function name
+and the parameter list, just as we did with generic *type* parameters.
+
+We want the signature to express the following constraint: the returned
reference will be valid as long as both the parameters are valid. This is the
relationship between lifetimes of the parameters and the return value. We’ll
name the lifetime `'a` and then add it to each reference, as shown in Listing
-10-22.
+10-21.
<span class="filename">Filename: src/main.rs</span>
```rust
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs:here}}
```
-<span class="caption">Listing 10-22: The `longest` function definition
+<span class="caption">Listing 10-21: The `longest` function definition
specifying that all the references in the signature must have the same lifetime
`'a`</span>
This code should compile and produce the result we want when we use it with the
-`main` function in Listing 10-20.
+`main` function in Listing 10-19.
The function signature now tells Rust that for some lifetime `'a`, the function
takes two parameters, both of which are string slices that live at least as
long as lifetime `'a`. The function signature also tells Rust that the string
slice returned from the function will live at least as long as lifetime `'a`.
In practice, it means that the lifetime of the reference returned by the
-`longest` function is the same as the smaller of the lifetimes of the
-references passed in. These relationships are what we want Rust to use when
-analyzing this code.
+`longest` function is the same as the smaller of the lifetimes of the values
+referred to by the function arguments. These relationships are what we want
+Rust to use when analyzing this code.
Remember, when we specify the lifetime parameters in this function signature,
we’re not changing the lifetimes of any values passed in or returned. Rather,
lifetimes of `x` and `y`.
Let’s look at how the lifetime annotations restrict the `longest` function by
-passing in references that have different concrete lifetimes. Listing 10-23 is
+passing in references that have different concrete lifetimes. Listing 10-22 is
a straightforward example.
<span class="filename">Filename: src/main.rs</span>
```rust
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs:here}}
```
-<span class="caption">Listing 10-23: Using the `longest` function with
+<span class="caption">Listing 10-22: Using the `longest` function with
references to `String` values that have different concrete lifetimes</span>
In this example, `string1` is valid until the end of the outer scope, `string2`
declaration of the `result` variable outside the inner scope but leave the
assignment of the value to the `result` variable inside the scope with
`string2`. Then we’ll move the `println!` that uses `result` to outside the
-inner scope, after the inner scope has ended. The code in Listing 10-24 will
+inner scope, after the inner scope has ended. The code in Listing 10-23 will
not compile.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore,does_not_compile
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs:here}}
```
-<span class="caption">Listing 10-24: Attempting to use `result` after `string2`
+<span class="caption">Listing 10-23: Attempting to use `result` after `string2`
has gone out of scope</span>
When we try to compile this code, we get this error:
```console
-{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt}}
+{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/output.txt}}
```
The error shows that for `result` to be valid for the `println!` statement,
that the reference is valid in this case. We’ve told Rust that the lifetime of
the reference returned by the `longest` function is the same as the smaller of
the lifetimes of the references passed in. Therefore, the borrow checker
-disallows the code in Listing 10-24 as possibly having an invalid reference.
+disallows the code in Listing 10-23 as possibly having an invalid reference.
Try designing more experiments that vary the values and lifetimes of the
references passed in to the `longest` function and how the returned reference
### Lifetime Annotations in Struct Definitions
-So far, the structs we've define all hold owned types. We can define structs to
+So far, the structs we’ve defined all hold owned types. We can define structs to
hold references, but in that case we would need to add a lifetime annotation on
-every reference in the struct’s definition. Listing 10-25 has a struct named
+every reference in the struct’s definition. Listing 10-24 has a struct named
`ImportantExcerpt` that holds a string slice.
<span class="filename">Filename: src/main.rs</span>
```rust
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs}}
```
-<span class="caption">Listing 10-25: A struct that holds a reference, so its
-definition needs a lifetime annotation</span>
+<span class="caption">Listing 10-24: A struct that holds a reference, requiring
+a lifetime annotation</span>
-This struct has one field, `part`, that holds a string slice, which is a
+This struct has the single field `part` that holds a string slice, which is a
reference. As with generic data types, we declare the name of the generic
lifetime parameter inside angle brackets after the name of the struct so we can
use the lifetime parameter in the body of the struct definition. This
You’ve learned that every reference has a lifetime and that you need to specify
lifetime parameters for functions or structs that use references. However, in
-Chapter 4 we had a function in Listing 4-9, shown again in Listing 10-26, that
+Chapter 4 we had a function in Listing 4-9, shown again in Listing 10-25, that
compiled without lifetime annotations.
<span class="filename">Filename: src/lib.rs</span>
```rust
-{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs:here}}
+{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs:here}}
```
-<span class="caption">Listing 10-26: A function we defined in Listing 4-9 that
+<span class="caption">Listing 10-25: A function we defined in Listing 4-9 that
compiled without lifetime annotations, even though the parameter and return
type are references</span>
These rules apply to `fn` definitions as well as `impl` blocks.
The first rule is that the compiler assigns a lifetime parameter to each
-parameter that’s a reference. In other words, a function with one parameter
-gets one lifetime parameter: `fn foo<'a>(x: &'a i32)`; a function with two
+parameter that’s a reference. In other words, a function with one parameter gets
+one lifetime parameter: `fn foo<'a>(x: &'a i32)`; a function with two
parameters gets two separate lifetime parameters: `fn foo<'a, 'b>(x: &'a i32,
y: &'b i32)`; and so on.
Let’s pretend we’re the compiler. We’ll apply these rules to figure out the
lifetimes of the references in the signature of the `first_word` function in
-Listing 10-26. The signature starts without any lifetimes associated with the
+Listing 10-25. The signature starts without any lifetimes associated with the
references:
```rust,ignore
the lifetimes in this function signature.
Let’s look at another example, this time using the `longest` function that had
-no lifetime parameters when we started working with it in Listing 10-21:
+no lifetime parameters when we started working with it in Listing 10-20:
```rust,ignore
fn longest(x: &str, y: &str) -> &str {
function rather than a method, so none of the parameters are `self`. After
working through all three rules, we still haven’t figured out what the return
type’s lifetime is. This is why we got an error trying to compile the code in
-Listing 10-21: the compiler worked through the lifetime elision rules but still
+Listing 10-20: the compiler worked through the lifetime elision rules but still
couldn’t figure out all the lifetimes of the references in the signature.
Because the third rule really only applies in method signatures, we’ll look at
lifetime of references in the struct’s fields, or they might be independent. In
addition, the lifetime elision rules often make it so that lifetime annotations
aren’t necessary in method signatures. Let’s look at some examples using the
-struct named `ImportantExcerpt` that we defined in Listing 10-25.
+struct named `ImportantExcerpt` that we defined in Listing 10-24.
First, we’ll use a method named `level` whose only parameter is a reference to
`self` and whose return value is an `i32`, which is not a reference to anything:
{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs:here}}
```
-This is the `longest` function from Listing 10-22 that returns the longer of
+This is the `longest` function from Listing 10-21 that returns the longer of
two string slices. But now it has an extra parameter named `ann` of the generic
type `T`, which can be filled in by any type that implements the `Display`
trait as specified by the `where` clause. This extra parameter will be printed