Variables are automatically freed at the end of their scope, using the drop function
Setting a variable to another non-primitive variable does a copy-by-reference, but unlike the usual approach in other languages, it also invalidates the variable it copied from. This means that if you try and use the original variable, you’ll get an error. This is for memory safety reasons. This process is called moving, since the value is essentially moved from one variable to another.
If you need to avoid invalidating the original variable, you’ll need to deliberately clone it (deep copy), which is more expensive. Rust will never deep clone by default
Primitives aren’t treated this way as they have fixed sizes, so can live on the stack.
Copy-by-reference / shallow copy = the data on the stack is copied, i.e. the pointer and some other data. This is cheap and fast
Copy-by-value / deep copy = the data on the heap is copied, i.e. the actual contents of the value. This is potentially a lot more expensive
Assigning a variable to a new value will immediately result in the previous value being freed via drop
By default, when a variable is passed into a function, that value is moved into the variable for the functions argument, and so the function takes ownership of that variable. Therefore once the scope of the function ends, the variable is dropped and the original variable becomes invalid.
To avoid this, we can pass a reference into a function, by prefixing the variable with the & symbol. The type of the argument in the function definition also needs to be prefixed with &
References do not take ownership of variables, and therefore a variable won’t be dropped/invalidated once passed to the function