liveBook · Manning

Reference

As explained in Rust in Action: Systems programming concepts and techniques

A reference is a non-owning value that provides access to another value without transferring its ownership.

A reference gives access to a value without taking ownership of it. Think of it as a way to find the original value rather than a duplicate of that value. Create one with `&`; use `*` to dereference it when you need the value it refers to. For example, `let r = &a; let b = a + *r;` uses `a` through `r` without making a second `a`. section 2.6

References matter when code needs access but the caller still needs its value afterward. A function that takes an owned value can leave the caller unable to use it again. Borrowing asks for less: `&T` provides read-only access, while `&mut T` provides read-write access. section 4.5 section 4.5.1

Choose the access the operation needs:

  • Use `for item in &collection` to read items and keep the collection available after the loop. section 2.4.1
  • Use `for item in &mut collection` when the loop must change items. section 2.4.1
  • Use an owned argument when the operation must take ownership. A function can borrow one argument while taking ownership of another. section 4.5.1

Send a message without giving away the satellite

A ground station can accept `to: &mut CubeSat` and `msg: Message`. Calling `send(&mut sat_a, msg)` lets the method change the satellite’s mailbox while the caller retains ownership of `sat_a` and can call `sat_a.recv()` afterward. The message itself moves into the mailbox. If `send` instead took `to: CubeSat`, ownership of the satellite would move into the function. section 4.5.1

Listing 4.13 Avoiding ownership issues with references
 #[derive(Debug)]
 struct CubeSat {
   id: u64,
   mailbox: Mailbox,
 }
 
 #[derive(Debug)]
 struct Mailbox {
   messages: Vec<Message>,
 }
 
 type Message = String;
 
 struct GroundStation;
 
 impl GroundStation {
     fn send(&self, to: &mut CubeSat, msg: Message) {
         to.mailbox.messages.push(msg);
     }
 }
 
 impl CubeSat {
     fn recv(&mut self) -> Option<Message> {
         self.mailbox.messages.pop()
     }
 }
 
 fn main() {
     let base = GroundStation {};
     let mut sat_a = CubeSat {
       id: 0,
       mailbox: Mailbox {
         messages: vec![],
       },
     };
 
     println!("t0: {:?}", sat_a);
 
     base.send(&mut sat_a,
               Message::from("hello there!"));     #1
 
     println!("t1: {:?}", sat_a);
 
     let msg = sat_a.recv();
     println!("t2: {:?}", sat_a);
 
     println!("msg: {:?}", msg);
 }

Follow the satellite before sending, after its mailbox receives the message, and after receiving it again. The call site and method signatures show which value is borrowed and which is moved. section 4.5.1

Underneath the syntax, a reference relates to an address in memory: it identifies where another value resides. Rust distinguishes references, which carry compiler safety guarantees, from raw pointers, which lack those standard guarantees and can be null. Raw pointers can be useful for examining memory, but reading through one is unsafe; prefer a reference when it provides the access you need. section 6.2 section 6.2.1

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Explains borrowing through loop syntax, function signatures, dereferencing, and memory addresses, then contrasts references with raw pointers.
Examples
Demonstrates array searching with dereferenced items and a satellite mailbox updated through a mutable reference.
What it assumes
Introduces memory and pointers without assuming prior systems-programming experience, while teaching reference syntax through examples.
What you can do after
Apply references in Rust loops and function arguments to read or change values without unnecessarily moving ownership.
How it connects
Connects references to ownership, borrowing, iteration, dereferencing, memory addresses, and raw pointers.

Also explained in

Compare how 17 books explain reference →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.