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
-
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
-
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.