Skip to content

Instantly share code, notes, and snippets.

@nilz3ro
Last active April 30, 2021 17:26
Show Gist options
  • Save nilz3ro/0c7e50f7b3797ca809469966bfd9b2a1 to your computer and use it in GitHub Desktop.
Save nilz3ro/0c7e50f7b3797ca809469966bfd9b2a1 to your computer and use it in GitHub Desktop.
Rust's Ownership principles.

Rust's Ownership Principles

Ownership

Ownership is is a core concept in Rust and it provides a way for Rust and its programmers to deal with memory management and reference validation. Each value in Rust has an Owner which is basically the scope that the value belongs to. This could be a function or block scope or a struct etc.

Move

When you pass a value to a function (and in other scenarios that I will skip over for brevity) the value is moved out of its current scope and becomes owned by the function. It then belongs to the function until it ends, when the value will be dropped or deallocated. This also happens when you shadow a variable that holds a value that isn't Copy.

let my_string = String::from("rust is awesome.");
let my_other_string = my_string;

The value belonging to my_string has now been moved to my_other_string, since String is not Copy. If you tried to use my_string again, you'd get an error from Rust's Borrow Checker.

Borrow

In cases where you don't want a function (or some other scope) to take ownership of a value, you can pass it to the function as a reference, or in Rust vocabulary, you can have the function borrow the value.

fn main() {
    let my_string = String::from("why is the mascot a crab?");
    
    borrow_and_print_question(&my_string);
    println!("we can still use it in this scope since it was just borrowed! {}", my_string);
    
    take_ownership_and_print_question(my_string);
    println!("oh no. This will upset the borrow checker... {}", my_string);
}

fn borrow_and_print_question(some_string: &String) {
    println!("Question: {}", some_string);
}

fn take_ownership_and_print_question(some_string: String) {
    println!("My Question: {}", some_string);
}

Like we talked about before, if you try to use a value after it has been moved, the borrow checker will remind you that this is not something that Rust will allow.

Lifetimes

Lifetimes are another principle of Rust's Ownership model which enables the Borrow Checker to guarantee that references will be valid when your program runs. This is helps to prevent dangling references and helps the Borrow Checker understand how different references relate to each other. A lifetime basically describes how long a given value will live, and therefore how long a reference to the value would be valid. A value's lifetime begins when it is first assigned and ends when it is last used. Ususally Rust's Borrow Checker automatically knows how long a reference to a value is valid but there are certain cases where you need to declare them explicitly, using generic lifetimes annotations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment