Skip to content

We are working on this site. Want to help? Open an issue or a pull request on GitHub.

Ownership and Borrowing

Ownership is Rust’s most unique feature and has deep implications for how the language works. It’s what enables Rust to make memory safety guarantees without needing a garbage collector.

In Rust, data can be stored in two places:

  • Fixed size
  • Fast access
  • Last-in, first-out
  • All data must have a known, fixed size
  • Dynamic size
  • Slower access
  • Memory is allocated at runtime
  • Returns a pointer to that location
  1. Each value has a variable that’s its “owner”
  2. There can only be one owner at a time
  3. When the owner goes out of scope, the value will be dropped
{                      // s is not valid here
    let s = String::from("hello");   // s is valid from this point forward
    // do stuff with s
}                      // this scope is now over, and s is no longer valid
let s = String::from("hello");
let s1 = String::from("hello");
let s2 = s1;  // s1's value moves to s2
// println!("{}", s1);  // This would cause an error
let s1 = String::from("hello");
let s2 = s1.clone();  // Deep copy
println!("{}", s1);  // This is fine
fn main() {
    let s = String::from("hello");
    takes_ownership(s);  // s's value moves into the function
    // println!("{}", s);  // This would cause an error
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
}  // some_string goes out of scope and is dropped
fn main() {
    let s1 = gives_ownership();
    let s2 = String::from("hello");
    let s3 = takes_and_gives_back(s2);
}

fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string
}

fn takes_and_gives_back(a_string: String) -> String {
    a_string
}

JavaScript uses garbage collection:

let s1 = "hello";
let s2 = s1;  // s1 is still valid
console.log(s1);  // "hello"

Ownership is a fundamental concept in Rust that enables memory safety without garbage collection.