Basic

Ownership Basics

Understand Rust's ownership rules that eliminate garbage collection.

What you will see

hi dropped

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

You will move values, borrow them with references, and see how scope frees memory.

1

I borrow a string to get its length without taking ownership. The borrow is temporary and ends after the call.

fn length(s: &str) -> usize { s.len() } fn main() { let s = String::from("hello"); let n = length(&s); println!("{}", n); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
5
2

I borrow the string mutably and append to it. The mutable borrow lets me change the original value.

fn main() { let mut s = String::from("hi"); s.push_str(" there"); println!("{}", s); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
hi there
3

I move a String into another variable, then try to use the first one. Using a moved value fails to compile.

fn main() { let s1 = String::from("hi"); let s2 = s1; println!("{}", s1); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
COMPILE_ERROR
After a move, the original variable can no longer be used.
4

I create two immutable borrows and print through both. Many immutable borrows can coexist at once.

fn main() { let s = String::from("hi"); let r1 = &s; let r2 = &s; println!("{} {}", r1, r2); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
hi hi
5

I create a value inside a block and confirm it is dropped when the block ends. When the owner goes out of scope, the memory is freed.

fn main() { { let s = String::from("hi"); println!("{}", s); } println!("dropped"); }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
hi dropped

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A value has one owner; borrows let others read without owning.
1 Create a value with an owner
↓
2 Borrow it with &s to read
↓
3 Or borrow mutably with &mut to change
↓
4 Borrows end when scope closes
Why this works
The three rules

Ownership has three rules:

  1. Each value has one owner.
  2. There can be only one owner at a time.
  3. The owner goes out of scope, the value is dropped.

{
    let s = String::from("hi");  // valid
}                                // s dropped here

When s goes out of scope, its memory is freed automatically.

Borrowing rules

References follow strict rules:

let mut s = String::from("hi");
let r1 = &s;       // ok
let r2 = &s;       // ok, two immutable borrows
// let r3 = &mut s; // error while r1, r2 exist

You may have many immutable borrows OR one mutable borrow, never both at once. This prevents reads during writes.

Examples

Ownership transfer

Moving values

let s1 = String::from("hi");
let s2 = s1;   // s1 is now invalid
// println!("{}", s1);  // error!

When you assign a String to a new variable, ownership moves. The old variable can no longer be used.

Why it works: ownership has a single owner at a time, so memory is freed deterministically.

Borrowing with references

Using without owning

fn length(s: &str) -> usize {
    s.len()
}

let s = String::from("hello");
let n = length(&s);   // borrow, do not move

A reference (&s) lets you use a value without taking ownership. The borrow is temporary and must not outlive the owner.

Why it works: references let functions read data without stealing it.

Mutable borrows

Borrowing mutably

let mut s = String::from("hi");
let r = &mut s;
r.push_str(" there");

&mut borrows mutably. At most one mutable borrow can exist at a time, or any number of immutable borrows, never both.

Why it works: this rule prevents data races at compile time.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Functions
Previous Lesson
Functions
Next Lesson
Structs and Methods
Structs and Methods →