|
4 | 4 | {{#include exercise.rs:solution}} |
5 | 5 | ``` |
6 | 6 |
|
7 | | -This solution highlights the difference between shared and mutable references: |
| 7 | +The solution demonstrates the fundamental distinction between shared and |
| 8 | +exclusive references: |
8 | 9 |
|
9 | | -- **Shared References (`&`):** `magnitude` needs to read the vector components |
10 | | - but not modify them, so it takes a shared reference (`&[f64; 3]`). |
11 | | -- **Mutable References (`&mut`):** `normalize` modifies the vector in place, so |
12 | | - it requires an exclusive mutable reference (`&mut [f64; 3]`). |
13 | | -- **Dereferencing:** In the `normalize` loop, `item` is a `&mut f64`. To modify |
14 | | - the actual value, we must dereference it using `*item`. |
15 | | -- **Iteration:** When we iterate over a reference to an array (like `vector`), |
16 | | - the iterator yields references to the elements. In `magnitude`, `coord` is |
17 | | - `&f64`. In `normalize`, `item` is `&mut f64`. |
| 10 | +- **Shared References (`&`):** Used in `magnitude` because the function only |
| 11 | + reads the vector components. |
| 12 | +- **Exclusive References (`&mut`):** Required in `normalize` to modify the array |
| 13 | + elements in place. |
| 14 | +- **Explicit Dereferencing:** Inside `normalize`, `item` is an `&mut f64`. We |
| 15 | + use `*item` to access and modify the underlying value. |
18 | 16 |
|
19 | 17 | <details> |
20 | 18 |
|
21 | | -- Note that in `normalize` we were able to do `*item /= mag` to modify each |
22 | | - element. This is because we're iterating using a mutable reference to an |
23 | | - array, which causes the `for` loop to give mutable references to each element. |
24 | | - |
25 | | -- It is also possible to take slice references here, e.g., |
26 | | - `fn |
27 | | - magnitude(vector: &[f64]) -> f64`. This makes the function more general, |
28 | | - at the cost of a runtime length check. |
| 19 | +- **Iterating over References:** Iterating over `&vector` or `&mut vector` |
| 20 | + yields references to the elements. This is why `coord` is `&f64` and `item` is |
| 21 | + `&mut f64`. |
| 22 | +- **Arrays vs. Slices:** The functions are defined using array references |
| 23 | + (`&[f64; 3]`), which ensures the length is known at compile time. Using slices |
| 24 | + (`&[f64]`) would make the functions more flexible but would introduce a |
| 25 | + runtime length check or potential for panics if the slice has the wrong size. |
| 26 | +- **Method Call Ergonomics:** In `magnitude`, we can call `mag_squared.sqrt()` |
| 27 | + directly. In `normalize`, we pass `vector` (an `&mut [f64; 3]`) to |
| 28 | + `magnitude`, and Rust automatically downgrades the exclusive reference to a |
| 29 | + shared reference to match the signature. |
29 | 30 |
|
30 | 31 | </details> |
0 commit comments