Rules
1. each value in Rust has an owner.
fn main() {
let s1 = String::from("Let's get Rusty");
}
the value is the heap-allocated string
the owner is the s1
variable
2. There can only be one owner at a time
so if we do this:
fn main() {
let s1 = String::from("Let's get Rusty");
let s2 = s1;
println!("{s1}");
}
we get the error borrow of moved value s1
s2 becomes the new owner of s1's value and printing s1 is invalid
but if we clone s1 (make a new copy of the value)let s2 = s1.clone();
This code would be valid.
passing values as arguments (moving a value) apply to rule 2 as well.
fn main() {
let s1 = String::from("Let's get Rusty");
let s2 = s1;
print_string(s2);
}
fn print_string(s: String) {
println!("{s}");
}
the argument s
becomes the new owner of s2
's value which leads to rule 3
3. When the owner goes out of scope, the value will be dropped.
so after the print_string
function finishes and the scope switches back to main(); the value owned by s gets dropped and cleaned up from memory (heap or stack)
There are ways to temporarily avoiding this ownership rule:
- using
.clone()
to make a copy (more memory) and passing that copy into the function. - or have the function pass the value back in the return statement.
References
instead of giving full ownership, we can pass a reference to the function.
fn main() {
let s1 = String::from("Let's get Rusty");
print_string(&s1);
print_string(&s1);
}
fn print_string(s: &str) {
println!("{s}");
}
This is called Borrowing