Introduction to Variable Ownership

Welcome! Today, we will navigate the realm of variable ownership in Rust. This principle forms the crux of Rust's performance and safety. To visualize this, consider how you solely possess a book before handing it to a sibling. Rust variables adhere to a similar convention. We'll delve into Copy and non-Copy types, understand variable ownership within functions.

Understanding Ownership in Rust

Variable ownership is the star feature of Rust that differentiates it from other languages. The three rules of ownership are:

  1. Each value in Rust has a variable that’s called its owner. This means that there's always one and only one variable bound to any given piece of data. There can only be one owner at a time.

  2. When you assign the value of one variable to another, the first variable will no longer hold that value if its type does not implement the Copy trait. We could say it's a bit like passing a baton in a relay race!

  3. When the owner goes out of scope, the value will be dropped. This means once the variable that owns the data is done (like at the end of the function or a block of code), Rust automatically cleans up and frees the memory associated with that data. It's like when you're done reading a library book and return it, the book is no longer in your possession and can be borrowed by someone else.

Dive into Copy Variables

Rust features the Copy trait for types of a fixed size that can be safely duplicated. When Copy types are assigned, the data is reproduced.

The following data types are Copy types:

  • integers and floating points (i32, f64, u32, etc.)
  • char
  • bool

Let's take a look at an example:

fn main() {
    let x = 5; // x, an integer, is a Copy type
    let y = x; // y receives a copy of x's value
    println!("x = {}, y = {}", x, y); // Here, x and y are both valid
}

In this code, y is assigned a duplicate of x’s value. Therefore, after the assignment operation, both x and y are valid. x and y each own their own value of 5.

Understanding Non-Copy Variables

Rust also encompasses non-Copy types, such as String, Vec<T>, etc. For these types, the actual data isn't copied, but the reference is. The 2nd rule of ownership dictates that when you assign the value of one variable to another, the first variable will no longer hold that value if its type does not implement the Copy trait.

Consider Strings (non-Copy types) as an example:

fn main() {
    let s1 = String::from("hello"); // s1 is a String, hence it's a non-Copy data type
    let s2 = s1; // here, s1's ownership is transferred to s2
    println!("{}", s1); // This will result in a compile-time error
}

In this snippet, once s1 is assigned to s2, s2 becomes the owner of the value, and s1 is invalidated.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal