Lifetimes in Data Structures
If a data type stores borrowed data, it must be annotated with a lifetime:
1. ```
#[derive(Debug)]
```
2. ```
struct Highlight<'doc>(&'doc str);
```
4. ```
fn erase(text: String) {
```
5. ```
println!("Bye {text}!");
```
6. ```
}
```
8. ```
fn main() {
```
9. ```
let text = String::from("The quick brown fox jumps over the lazy dog.");
```
10. ```
let fox = Highlight(&text[4..19]);
```
11. ```
let dog = Highlight(&text[35..43]);
```
12. ```
// erase(text);
```
13. ```
println!("{fox:?}");
```
14. ```
println!("{dog:?}");
```
15. ```
}
```
This slide should take about 5 minutes.
- In the above example, the annotation on
Highlightenforces that the data underlying the contained&strlives at least as long as any instance ofHighlightthat uses that data. - If
textis consumed before the end of the lifetime offox(ordog), the borrow checker throws an error. - Types with borrowed data force users to hold on to the original data. This can be useful for creating lightweight views, but it generally makes them somewhat harder to use.
- When possible, make data structures own their data directly.
- Some structs with multiple references inside can have more than one lifetime annotation. This can be necessary if there is a need to describe lifetime relationships between the references themselves, in addition to the lifetime of the struct itself. Those are very advanced use cases.
