# 9.x Chapter 9 summary and quiz > Review of references, borrowing, the borrow checker, dangling references, and slices, with a chapter quiz and a capstone program. Source: https://learnrust.net/chapter-9/chapter-9-summary-and-quiz/ Chapter 8 taught Rust's strictest idea; this chapter taught the idea that makes the strictness livable. Quick review, and then the quiz makes you use all of it at once. ## Quick review A **reference** is a value that refers to another value without owning it; creating one is called **borrowing** ([9.1](@/chapter-9/references-borrowing-a-value.md)). The `&` appears on both sides of an agreement: `&message` at the call site lends, `text: &String` in the signature receives. A reference owns nothing, so dropping one frees nothing, and the borrowed value's one true owner carries on untouched. Plain `&` references are read-only, and any number may exist at once. A **mutable reference**, spelled `&mut`, is a loan with writing permission ([9.2](@/chapter-9/mutable-references.md)). Mutation is written down three times (a `mut` binding, `&mut` at the call site, `&mut T` in the signature), which is why `read_line(&mut name)` looks the way it has since chapter 1. The **borrow checker** enforces the chapter's two rules: at any given time a value has *either* one mutable reference *or* any number of immutable ones, and references must always be valid. Borrows last from creation to *last use*, not to the closing brace, so reordering a few lines is a legitimate and common fix. The four refusals you'll meet most ([9.3](@/chapter-9/the-borrow-checker-is-your-friend.md)): E0596 (borrowing `&mut` from a non-`mut` binding), E0502 (writer while readers live), E0382 (use after move, usually cured with `&` rather than `.clone()`), and E0506 (assigning over a borrowed value). Parameter design is a four-row table ([9.4](@/chapter-9/references-and-functions.md)): Copy types by value, `&T` to read, `&mut T` to modify in place, owned `T` to keep or consume. Results travel in return values, not `&mut` out-parameters. A **dangling reference**, one that outlives its value, is rule 2's forbidden object ([9.5](@/chapter-9/dangling-references.md)): a function can return a reference only if it borrows from something living outside the call, which is why returning a view of a *parameter* compiles and returning a view of a *local* is refused at the signature. A **lifetime** is the stretch of program during which a value is alive; `'static`, the whole-program lifetime of string literals, is the only one you'll spell until chapter 17. A **slice** is a reference with a range: `&temperatures[1..4]` borrows a view of part of a sequence, of type `&[i32]`, an address plus a length ([9.6](@/chapter-9/slices.md)). Functions take slices rather than arrays for the same reason text functions take `&str` rather than `&String`, and that reason is now mechanical: **deref coercion** and its sibling conversions shrink an owner-shaped argument into the view a parameter asks for ([9.7](@/chapter-9/string-slices.md)). A **string slice** is precisely that machinery aimed at text. Carve with byte indexes at character boundaries or Rust panics rather than splits a `char`; views found by scanning the text itself are always safe. The chapter's thesis, witnessed in transcript form: the index version of `first_word` shipped a stale-bookkeeping bug, and the slice version made the same bug *fail to compile*. The borrow checker isn't only guarding memory. It guards the connection between your data and the facts you derive from it. ## Quiz time **Question #1** From memory: state the two rules of references, and name the part of the compiler that enforces them.
Show solution At any given time, a value can have either one mutable reference or any number of immutable references; and references must always be valid. The enforcer is the borrow checker. If you can also explain *why* each rule exists (readers must never watch a value change or vanish mid-look; a reference must never outlive its value), the chapter did its job.
**Question #2** Compiles or not? For each failure, name the error code. a) ```rust fn main() { let recipe = String::from("toast"); let a = &recipe; let b = &recipe; println!("{a} and {b}"); } ``` b) ```rust fn main() { let mut recipe = String::from("toast"); let a = &recipe; recipe.push_str(" with jam"); println!("{a}"); } ``` c) ```rust fn main() { let recipe = String::from("toast"); let copy = recipe; println!("{recipe}"); } ``` d) ```rust fn main() { let mut recipe = String::from("toast"); let a = &mut recipe; a.push_str(" with jam"); let b = &mut recipe; b.push_str(" and tea"); println!("{recipe}"); } ```
Show solution a) Compiles: any number of readers, `toast and toast`. b) Refused, E0502: `a` is a live reader (used in the `println!`) when `push_str` needs a writable loan. c) Refused, E0382: chapter 8's move, no references involved at all. `let copy = recipe;` ends `recipe`. d) Compiles, printing `toast with jam and tea`. Two mutable borrows, but *taking turns*: `a`'s last use is its `push_str`, so it's gone before `b` is created. One writer at a time, not one writer per lifetime of the value.
**Question #3** Match each snippet to its error code (E0382, E0499, E0502, E0506, E0596). One code per snippet, no compiler. a) ```rust let mut s = String::from("hi"); let r1 = &mut s; let r2 = &mut s; println!("{r1} {r2}"); ``` b) ```rust let s = String::from("hi"); let r = &mut s; r.push_str("!"); ``` c) ```rust let mut s = String::from("hi"); let r = &s; s = String::from("bye"); println!("{r}"); ``` d) ```rust let s = String::from("hi"); let t = s; println!("{s}"); ``` e) ```rust let mut s = String::from("hi"); let r = &s; s.push_str("!"); println!("{r}"); ```
Show solution a) E0499, two simultaneous writers (the one combination the clinic lesson's patients didn't cover, and the code 9.2 introduced). b) E0596, writable loan against a non-`mut` binding. c) E0506, assigning over a borrowed value. d) E0382, use after move. e) E0502, writer while a reader lives.
**Question #4** The capstone. Write a program that reads a line of text, prints its first word, then prints that word shouted with excitement added. Requirements: a `first_word(s: &str) -> &str` (yours from lesson 9.7, or rewrite it), a `shouted(text: &str) -> String`, and an `add_excitement(text: &mut String)` that appends `!!!`. Sample run, typing `go rust go`: ``` first word: go GO!!! ``` Design check before you peek: which of your functions borrow, which one needs a writable loan, and which value in `main` owns heap text?
Show solution ```rust use std::io; fn first_word(s: &str) -> &str { let bytes = s.as_bytes(); let mut i = 0; while i < bytes.len() { if bytes[i] == b' ' { return &s[..i]; } i += 1; } s } fn shouted(text: &str) -> String { text.to_uppercase() } fn add_excitement(text: &mut String) { text.push_str("!!!"); } fn main() { let mut input = String::new(); io::stdin().read_line(&mut input).expect("failed to read line"); let phrase = input.trim(); let word = first_word(phrase); println!("first word: {word}"); let mut cheer = shouted(word); add_excitement(&mut cheer); println!("{cheer}"); } ``` Design notes, with 9.4's table doing the deciding. Two owners live in `main`: `input` (the read buffer; `read_line` takes the program's first `&mut`) and `cheer` (built by `shouted`, an owned return per 9.5: the function creates new text, so a view is impossible). Everything else is borrowed: `phrase` is `trim`'s view into `input`, `word` is `first_word`'s view into that view, and both functions that only read (`first_word`, `shouted`) take `&str`, so they'd accept literals just as happily. `add_excitement` is the legitimate `&mut` case: modifying a value the caller keeps, with the consent visible at the call site. And the borrows take turns: `word`'s last use is the `shouted` call, after which `input`'s readers are done; nothing overlaps, nothing is cloned, and the only text ever copied is the uppercase version, which had to be new. If your version cloned somewhere, or a function took `String` and you had to give one back: those compile too, and chapter 8 explains what they cost. The ownership-and-borrowing way is the one where the signatures alone tell the story.
Eight chapters of `String` and numbers were the price of admission. With ownership (chapter 8) and borrowing (this chapter) in hand, you can finally be trusted with the keys to the type system: chapter 10 lets you define types of your own, and the `&self` in every method you'll ever write is this chapter wearing a new coat.