# 9.1 References: borrowing a value > Rust references let functions use a value without taking ownership: the & operator, borrowing, and why references are immutable by default. Source: https://learnrust.net/chapter-9/references-borrowing-a-value/ Chapter 8 closed with a promise: every awkward moment in it (the tuple dance, the defensive clone, the function that swallowed your `String`) dissolves into a single character. Time to collect. Here's the give-and-take-back dance from lesson [8.6](@/chapter-8/ownership-and-functions.md) one last time, a function that needs to hand its argument back because using it consumed it: ```rust fn measure(text: String) -> (String, usize) { let len = text.len(); (text, len) } fn main() { let message = String::from("hello"); let (message, len) = measure(message); println!("{message} is {len} bytes long"); } ``` ``` hello is 5 bytes long ``` It works, and it's miserable. `measure` wants to *look at* a `String`, but the only tool chapter 8 gave us hands over the whole value, so the function must mail it back in a tuple, and the caller must unpack it. Asking someone the time shouldn't require giving them your watch. ## The `&` fix Here's the same program the way a Rust programmer would actually write it: ```rust fn measure(text: &String) -> usize { text.len() } fn main() { let message = String::from("hello"); let len = measure(&message); println!("{message} is {len} bytes long"); } ``` ``` hello is 5 bytes long ``` No tuple, no dance, and `main` keeps using `message` after the call as if nothing happened. Because nothing did happen: `message` never stopped being the owner. Lesson 8.6 named the words in passing; this is where they live. The `&message` at the call site creates a **reference**: a value that *refers to* another value without owning it. Creating a reference to a value is called **borrowing** the value, and the vocabulary is well chosen. When you borrow a book, the book still belongs to its owner; you're expected to look at it, not burn it, and eventually you give it back. No part of that transaction transfers ownership. Read the two ampersands aloud and the signature becomes a sentence. At the call site, `&message` says "lend `measure` a view of `message`." In the signature, `text: &String` says "I accept a borrowed `String`; I will not be keeping it." They're two halves of one agreement, written down on both sides of the call, which is exactly where you want an agreement written. If the word *view* is ringing a bell, it should. Lesson [5.4](@/chapter-5/introduction-to-str.md) introduced `&str` as a viewer watching text through a window while a `String` owns it. That wasn't a special trick for strings. It was your first reference, and as of today every `&` in the language is one: a cheap, non-owning window onto a value that someone else keeps alive. ## What a reference looks like in memory Lesson 8.2 gave us the picture for a `String`: a small fixed-size handle in the stack frame (address of the heap block, length, capacity), with the actual text in the block. A reference adds one more small box to the picture: it holds the address of the *handle*. Following the trail from `text` to `message` to the heap is the compiler's problem, not yours; the part that matters is what the reference doesn't hold, which is ownership of anything. That answers the question chapter 8 trained you to ask: who cleans up? Inside `measure`, the parameter `text` goes out of scope at the closing brace, and... nothing happens to the `String`. Dropping a reference frees nothing, because the reference owns nothing. The watcher leaving the window doesn't bulldoze the bicycle. `message` is dropped exactly once, at the end of `main`, by its one and only owner, and the three rules of ownership from lesson [8.1](@/chapter-8/introduction-to-ownership.md) come through without a scratch. ## References are immutable by default Borrowing a book comes with an unspoken rule: no writing in the margins. References have the same rule, and it's enforced. A plain `&` reference lets you read the value, full stop. Watch what happens when a function tries to go further: ```rust fn add_world(text: &String) { text.push_str(", world"); } fn main() { let message = String::from("hello"); add_world(&message); } ``` ``` error[E0596]: cannot borrow `*text` as mutable, as it is behind a `&` reference --> src/main.rs:2:5 | 2 | text.push_str(", world"); | ^^^^ `text` is a `&` reference, so it cannot be borrowed as mutable | help: consider changing this to be a mutable reference | 1 | fn add_world(text: &mut String) { | +++ ``` Apply your lesson [1.7](@/chapter-1/reading-compiler-errors.md) training. The headline says we tried to mutate something "behind a `&` reference". The label under the caret restates it as a plain sentence: this is a `&` reference, so writing through it isn't allowed. And the help block, as usual, is the compiler reading ahead in the syllabus: there exists something called a *mutable reference*, spelled `&mut`, and it would make this program legal. That's the next lesson, and you've technically been using it since lesson [1.6](@/chapter-1/reading-input.md). Defaulting to read-only is the same design taste you met in lesson 1.4, where variables are immutable until you say `mut`. A function that takes `&String` is making a promise the compiler will hold it to: *I only look.* When you call it, you can hand over a view of your most precious data without reading the function's body first, because the signature already told you the worst it can do. ## The two rules Everything this chapter does flows from two rules, so here's the map before we walk the terrain: 1. At any given time, a value can have *either* one mutable reference *or* any number of immutable references. 2. References must always be valid. Rule 1 is the subject of lessons [9.2](@/chapter-9/mutable-references.md) and [9.3](@/chapter-9/the-borrow-checker-is-your-friend.md), and rule 2 belongs to lesson [9.5](@/chapter-9/dangling-references.md). The part of the compiler that enforces them has a name you've been promised since chapter 5: the **borrow checker**. By the end of the chapter you'll have seen it refuse half a dozen programs, and the point of every refusal is the same: each one is a real bug, of a kind that some very expensive C++ ships with. {% callout(kind="note", title="Key insight") %} Any number of `&` references to the same value can exist at once, and that's fine, for the same reason ten neighbors can watch one bicycle. Readers don't interfere with each other. It's *writing* that needs rules, and that's precisely where Rust draws the line. {% end %} ## Quiz time **Question #1** In `let len = measure(&message);`, what does the `&` do, and what does `measure` own while it runs?
Show solution The `&` creates a reference to `message` and lends it to `measure`: borrowing, not giving. While it runs, `measure` owns nothing of `message`'s. Its parameter is a view; `message` in `main` remains the owner throughout, which is why `main` can keep using it after the call.
**Question #2** What does this program print? (Compare it with lesson [8.4](@/chapter-8/moves.md) before answering.) ```rust fn main() { let city = String::from("Nairobi"); let view = &city; println!("{view}"); println!("{city}"); } ```
Show solution ``` Nairobi Nairobi ``` In lesson 8.4, `let s2 = s1;` *moved* the value and ended `s1`. Here `let view = &city;` merely borrows it, so `city` stays alive and usable. One character is the whole difference between "gave it away" and "let someone look".
**Question #3** Predict the compiler's reaction, then give the one-character fix: ```rust fn measure(text: &String) -> usize { text.len() } fn main() { let message = String::from("hello"); let len = measure(message); println!("{message} is {len} bytes long"); } ```
Show solution `error[E0308]: mismatched types` at the call: expected `&String`, found `String`, with the compiler's help line offering `consider borrowing here`, i.e. `measure(&message);`. The signature asks for a loan and the call offers a gift; the types disagree, so the program is refused before the move (and the use-after-move on the next line) can even be judged. Add the `&`.
A read-only window covers functions that look. It doesn't cover `read_line`, which has been *writing* into your Strings since chapter 1 on an IOU. Next lesson, the `&mut` tab finally gets settled.