|
4 | 4 | {{#include ../../third_party/rust-on-exercism/health-statistics.rs:solution}} |
5 | 5 | ``` |
6 | 6 |
|
7 | | -- **Lifetimes in Structs:** `HealthReport` has a lifetime parameter `'a` because |
8 | | - it contains a reference `patient_name: &'a str`. This ensures that the report |
9 | | - cannot outlive the `User` it refers to. |
10 | | -- **Mutable Reference (`&mut self`):** `visit_doctor` modifies the `User` |
11 | | - struct, so it must take `&mut self`. |
12 | | -- **Lifetime Elision:** The return type `HealthReport<'_>` indicates that the |
13 | | - output lifetime is tied to the input lifetime of `self`. Explicitly, this |
14 | | - would be `fn visit_doctor<'a>(&'a mut self, ...) -> HealthReport<'a>`. |
15 | | -- **Option combinators:** We use `self.last_blood_pressure.map(...)` to |
16 | | - convenienty calculate the blood pressure change if the previous measurement |
17 | | - exists. |
| 7 | +The solution explores how structs can capture references and how lifetimes tie |
| 8 | +related data structures together: |
| 9 | + |
| 10 | +- **Lifetimes in Structs:** `HealthReport` contains a reference |
| 11 | + `patient_name: &'a str`, which necessitates a lifetime parameter `'a`. This |
| 12 | + guarantees that a report cannot outlive the `User` it was created from. |
| 13 | +- **Mutable Borrows:** `visit_doctor` takes `&mut self` to update the user's |
| 14 | + stats. Because it returns a `HealthReport` that borrows from `self`, the |
| 15 | + report's lifetime is tied to the duration of this borrow. |
| 16 | +- **Idiomatic `Option` Handling:** `self.last_blood_pressure.map(...)` is used |
| 17 | + to concisely compute the change in blood pressure only when a prior value is |
| 18 | + available. |
18 | 19 |
|
19 | 20 | <details> |
20 | 21 |
|
21 | | -- Explain that `HealthReport` borrows from `User`. While `report` exists, `User` |
22 | | - is borrowed (mutably, because it came from `visit_doctor`), so we cannot use |
23 | | - `User` for anything else until `report` is dropped. |
24 | | -- Note the cast to `i32` for blood pressure calculation to allow for negative |
25 | | - changes. |
| 22 | +- **Lifetime Elision:** The signature |
| 23 | + `fn visit_doctor(&mut self, ...) -> |
| 24 | + HealthReport<'_>` uses anonymous |
| 25 | + lifetimes. The compiler expands this to indicate that the returned report |
| 26 | + borrows from `self`, effectively making the user inaccessible while the report |
| 27 | + is in scope. |
| 28 | +- **Borrows and Mutation:** Inside `visit_doctor`, the report must be created |
| 29 | + _before_ the user's fields are updated, as creating a reference to `self.name` |
| 30 | + borrows `self`. In Rust, you cannot modify a value while it is borrowed. |
26 | 31 |
|
27 | 32 | </details> |
0 commit comments