Ownership the set of rules that govern how Rust manages memory.

Ownership Rules

  • Each value in Rust has a owner
  • There can only be 1 owner at a time.
  • When a owner goes out of scope, the value will be dropped.

Resource Acquisition is Initialization - Resources deallocated at the end of a item’s lifetime.

Ownership Example:

    let s1: String = String::from("hello");
    let s2: String = s1;
    println!("{}, world!", s1); // ERROR, s2 now has ownership
  • s2 has ownership of the heap string ‘hello’ after it is set equal to s1.
  • s1 was invalidated. Think of s2 = s1 as a “move” of ownership.
    let s1: String = String::from("hello");
    let s2: String = s1.clone();
    println!("{}, world!", s1); // works fine

Copy and Drop

  • copy trait is one used by stack allocated variables.
let x = 5;
let y = x;
println!("x = {}, y = {}", x, y); // works because stack
  • Integers implement the ‘copy’ trait and therefore can be used on the stack.
    • The above example is possible with types implementing copy trait.
  • drop is used by heap allocated variables and is called at the end of lifetime (RAII)
  • Drop and Copy cannot both be present at the same time.

Ownership and Functions

Invalidity Example:

fn main() {
  let s = String::from("hello");
  takes_ownership(s);
  
  // s is no longer valid here
}
// Will take ownership of astr and then 'drop' it 
fn takes_ownership(astr: String) {
  println!("{}", astr);
}

Take and Return Example:

fn main() {
  let s1 = String::from("hello"); // gives ownership to s1
  let s1 = takegive(s1);
}
fn takegive(astr: String) -> String {
  return astr;
}

Borrowing

Taking and returning is ‘annoying’, what if we just used references?

Syntax: &var — creates a reference that refers to var, but does not own it.

  • Value it points to will not be dropped when reference stops being used.

Changing Borrowed Values By default you cannot modify a borrowed value. However, with a mutable reference:

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

Restriction

  • Only 1 mutable reference at a time
  • Cannot have both mutable and immutable references present.

Slices

  • A form of borrowing, where you borrow part of an array (or string)