liveBook · Manning

Ownership

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

An owner is the binding or program entity responsible for cleaning up a value when its lifetime ends.

In Rust, every value has an owner responsible for cleanup when the value’s lifetime ends. A lifetime is the period during which accessing a value is valid. When a value goes out of scope, the compiler arranges for its destructor to run; ordinary Rust code usually does not call destructors directly. Ownership does not give a binding exclusive permission to access its value: other code can borrow it. section 4.0 section 4.3

An owner can change without the data physically moving. Assignment, passing a value into a function, and returning it from a function can all transfer ownership. After a move, the previous binding cannot be used to access that value. section 4.1.1 section 4.4

error[E0382]: use of moved value: `sat_a`
  --> code/ch4-check-sats-2.rs:26:31
   |
 |   let a_status = check_status(sat_a);
   |                               ----- value moved here
...
 |   let a_status = check_status(sat_a);
   |                               ^^^^^ value used here after move
   |
   = note: move occurs because `sat_a` has type `CubeSat`,
   = which does not implement the `Copy` trait
 
...      #1
 
error: aborting due to 3 previous errors

The compiler marks the first call as the move and rejects the second use of `sat_a`. The error also notes that `CubeSat` does not implement `Copy`. section 4.1.1

One way to make the satellite available again is to return it. A `check_status(sat_id: CubeSat) -> CubeSat` function receives ownership as an argument, prints the status, and returns `sat_id`. The caller binds that returned value to `sat_a`, allowing another status check later. This works, but passing ownership back and forth is not always the simplest design. section 4.4

Listing 4.7 Returning ownership back to the original scope
 #![allow(unused_variables)]
 
 #[derive(Debug)]
 struct CubeSat {
   id: u64,
 }
 
 #[derive(Debug)]
 enum StatusMessage {
   Ok,
 }
 
 fn check_status(sat_id: CubeSat) -> CubeSat {
   println!("{:?}: {:?}", sat_id, StatusMessage::Ok);
   sat_id
 }
 
 fn main () {
   let sat_a = CubeSat { id: 0 };
   let sat_b = CubeSat { id: 1 };
   let sat_c = CubeSat { id: 2 };
 
   let sat_a = check_status(sat_a);      #1
   let sat_b = check_status(sat_b);
   let sat_c = check_status(sat_c);
 
   // "waiting" ...
 
   let sat_a = check_status(sat_a);
   let sat_b = check_status(sat_b);
   let sat_c = check_status(sat_c);
 }

Follow `sat_a` through two calls: each call takes ownership, and each return gives the caller a value it can bind again. section 4.4

When an ownership move makes later code awkward, choose a design that matches the access needed:

  • Use a reference when the function needs access rather than full ownership. section 4.5
  • Duplicate the value where appropriate; `Clone` and `Copy` are ways to do so. section 4.6
  • Shorten how long values stay around, or use a type designed to help with movement issues. section 4.5

The cleanup responsibility also constrains lifetimes: a value cannot outlive its owner. Custom cleanup can be supplied by implementing `Drop`, whose `drop(&mut self)` method performs wind-up work. That is generally unnecessary for ordinary values; the compiler inserts the usual cleanup calls. section 4.3

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

How deep it goes
Explains moves across assignments and function calls, destructor cleanup, and practical remedies without developing unsafe allocation details.
Examples
Traces repeated satellite status checks that fail after a move, then succeed when the function returns the satellite.
What it assumes
Builds from variables, structs, and function calls, while introducing ownership and its relationship to lifetimes and borrowing.
What you can do after
Diagnose/debug with it by locating moves behind use-after-move errors and choosing references, duplication, or shorter-lived values.
How it connects
Connects ownership to lifetimes, borrowing, destructors, references, and the Clone and Copy traits.

Also explained in

Compare how 6 books explain ownership →

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.