Ownership in Rust
In Rust, memory is managed through a system of ownership with a set of rules that the compiler checks at compile time
.
Rust follows three fundamental rules of ownership.
- Each value in rust has a variable that's called its owner.
let x = String::from("hello"); // string "hello" has its owner: x
- There can be only one owner at a time.
let x = String::from("hello");
let text = x; // string "hello" has been moved to text.
println!("x value is {x}"); // show compile error. x's value has been moved out.
- When the owner goes out of scope, the value will be dropped.
fn my_func() {
let x = String::from("hello");
println!("x value is {x}");
} // x is out of scope, the value "hello" will be dropeed.
The ownership of variable (except from primitive types) follows the same pattern every time: assigning a value to another variable moves it.
Stack Only Data : Copy
All primitive types
implement the Copy
trait and their ownership is therefore not moved like one would assume, following the ‘ownership rules’. [1]
- Primitive data are known-sized data at compile time, so rust
copy
the variable instead ofmove
.
let x = 10;
let y = x; // y is copied from x
println!("x is {x} and y is {y}");
compound type as example:
let arr: [i32; 5] = [1,2,3,4,5];
let arr_2 = arr; // copy on assignment.
println!("arr is {:} and arr_2 is {:}", arr, arr_2);
Exceptions
Any primitive compound type that contains non-primitive
types (e.g. String
or Vector
) are still follow move
on assignment.
arr_2
is move
on assignment rather than copy
.
let arr = [String::from("Chester"), String::from("John"), String::from("Marry")];
let arr_2 = arr; // move on assignment
tuple_2
is move
on assignment rather than copy
.
let tuple = (100, String::from("hello"));
let tuple_2 = tuple; // move on assignment
Moves on Index Content
We can not move out the index of Vector
, e.g.
let e = v[1]
is forbidden because we can not move out the indexed content from the owned variable.
let v = vec!["1".to_string(), "2".to_string(), "3".to_string()];
let e = v[1];
How to fix it ?
Use reference:
let v = vec!["1".to_string(), "2".to_string(), "3".to_string()];
let e = &v[0];