Ownership

fn main() {
    let a = [1, 2, 3];
    let b = a;
    println!("{:?} {:?}", a, b); // [1, 2, 3] [1, 2, 3]
}

fn main() {
    let a = vec![1, 2, 3];
    let b = a;
    println!("{:?} {:?}", a, b); // Error; use of moved value: `a`
}

In the above examples, we are just trying to assign the value of a to b . Almost the same code in both code blocks, but having two different data types. And the second one gives an error. This is because of the Ownership.

What is ownership?

⭐️ Variable bindings have ownership of what they’re bound to. A piece of data can only have one owner at a time. When a binding goes out of scope, Rust will free the bound resources. This is how Rust achieves memory safety.

Ownership (noun)
The act, state, or right of possessing something.

Copy types & move types

⭐️ When assigning a variable binding to another variable binding or when passing it to a function(Without referencing), if its data type is a

  1. Copy Type

    • Bound resources are made a copy and assign or pass it to the function.
    • The ownership state of the original bindings is set to “copied” state.
    • Mostly Primitive types
  2. Move type

    • Bound resources are moved to the new variable binding and we can not access the original variable binding anymore.
    • The ownership state of the original bindings is set to “moved” state.
    • Non-primitive types

🔎 The functionality of a type is handled by the traits which have been implemented to it. By default, variable bindings have ‘move semantics.’ However, if a type implements core::marker::Copy trait , it has a ‘copy semantics’.

💡 So in the above second example, ownership of the Vec object moves to b and a doesn’t have any ownership to access the resource.