I’m studying the Rust programming language now and geez is the concept of ownership interesting. This post is about the ownership and is written purely as way to help me remember. See the book for actual details.

The Rules

Keep these rules in mind as you work with Rust Ownership (copied directly from the book linked above)

  • Each value in Rust has a variable that’s called it’s owner.
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

The Concept of Ownership

  • Rust’s notion of scope is similar to other languages. However there is a difference that you have to know; spoiler, it’s ownership.
  • The primary difference is that allocated memory is automatically ‘drop’ed when it goes out of scope. Rust automatically calls ‘drop’ at the closing curly bracket.

Moving a variable:

// s1 "owns" the string value
let s1 = String::from("hello");

// ownership of the string value has been moved to s2
let s2 = s1;

// this won't work as s1 no longer owns a string
println!("{}, world!", s1);

// note that passing a variable into a function also passes ownership to that function

Deep copy or Cloning a variable on the heap

// s1 "owns" the string value
let s1 = String::from("hello");

// s2 is a clone of s1 but it owns the clone
let s2 = s1.clone();

// this works fine as both variables own their own values
println!("s1 = {}, s2 = {}", s1, s2);

Stack only variables are copied

Types whose size is entirely know at compile time are stored on the stack. You can check the documentation for types that implement the Copy trait.

let x = 5;
let y = x;

// works because these are copy'able' values
println!("x = {}, y = {}", x, y);

References and Borrowing

When you send a variable reference to a function, that function does not take ownership of the variable, it only borrows the value.

let s1 = String::from("hello");
let size = test(&s1); // we send a reference

fn test(s: &String) -> usize { // and the test function borrows it
    s.len()
}

Mutable References

If you need to pass a reference to a function and you need to allow the function to change the value the reference points to, you need to use a mutable reference. WARNING: Rust allows only one mutable reference to a value at a time.

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

Dangling references

A dangling reference happens when you have a pointer to nothing. Rust doesn’t allow this to happen.

fn main() {
    let bleh = dangle();
}

fn dangle() -> &String {
    let s = String::from("test");
    &s
}

The rules of references

Copied straight from the online book:

  • At any given time, you can have either one mutable reference or any number of immutable references.
  • References must always be valid.