When a variable is passed to a function, it can either be passed by reference (borrow, using & or &mut), or moved (move, without a reference).
Borrow: a reference to the data is passed. The data remains accessible after the function call, but with an immutable reference, the content cannot be changed, and with a mutable reference, there can only be 1 active reference.
fn read_length(s: &String) -> usize { s.len() }
Move: the variable completely "moves" into the function. After passing it, you cannot use the original variable - it has been moved, and any attempt to access it will result in a compile error.
fn destroy(s: String) { println!("{}", s); } // s will be dropped on exit let s = String::from("world"); destroy(s); // s can no longer be used
This prevents double freeing of memory and other ownership errors.
Can I use a variable after it has been passed to a function by value (move)?
No! After passing a variable by value – for example, String – the original variable becomes invalid:
let s = String::from("abc"); consume(s); // s is no longer valid here println!("{}", s); // compile error
Many confuse this with the behavior of types that implement Copy (like i32), where the variable remains valid after passing.
Story
A young programmer wrote a string processing function that took String instead of &String. As a result, the original string became unavailable after the function call, leading to double loading and additional memory allocation in the logging server.
Story
In one microservice, a critical resource was passed across different threads using move, after which attempts to access this resource in the main thread led to compile errors. Urgent refactoring of the architecture was required so that the resource was passed by reference or through wrappers like Arc.
Story
In an internal event parser, a variable was rapidly taken (moved) into a closure, after which accesses to it outside the closure caused compile errors. The problem was only noticed during a review - a style was introduced mandating the use of borrow for data that should outlive the local function.