In this lesson, you will learn how passing variables to functions acts as a "hand-off" of responsibility for the data, which determines whether you can still use that variable afterward.
The Hand-off Mechanism
When you pass a variable to a function in Rust, the function becomes the new owner of that data. Think of it like handing a physical book to a friend: once you give it away, you no longer have it in your hands. Unless your friend hands it back, you cannot read it anymore.
In Rust, this is called a "move." If the data type does not implement the Copy trait (like a String or a Vec), the original variable is considered invalidated the moment it enters the function.
A Concrete Example
Consider this snippet:
fn take_ownership(my_string: String) {
println!("I own the string: {}", my_string);
} // The string is dropped (cleaned up) here.
fn main() {
let s = String::from("Hello, Rust!");
take_ownership(s); // 's' is moved into the function.
// println!("{}", s); // Error! 's' is no longer valid.
}
When we call take_ownership(s), the responsibility for the String is transferred to the my_string variable inside the function scope. The main function loses access to s immediately. When take_ownership finishes, its scope ends, and the data is dropped from memory.
Why Does This Happen?
This behavior ensures memory safety. By enforcing a single owner, Rust guarantees that data is only cleaned up once and that no two parts of your program try to modify or access the same memory concurrently without explicit permission.
If you want to pass data to a function without losing it, you will eventually learn about borrowing (using references). However, for now, remember that simple assignment of non-Copy types into function arguments is a destructive action for the caller.
Key Takeaway: Passing a non-Copy variable to a function transfers ownership, making the original variable inaccessible in the calling scope.