Why does passing a struct to a function in Rust permanently move it to that function?

Viewed 314

Example:

let mut protagonist = Vec::new(); 
for (_i, _c) in challenger.chars().enumerate() {   
    protagonist.push('_');
}
let s = String::from_iter(protagonist);

protagonist.push('t'); // error: value borrowed here after move

I know that in order to solve it you have to write &protagonist instead when passing it to the from_iter() function. As in pass by reference, instead of value. But my question is why does the object move away in the first place when you pass by value and you can no longer use it anymore in your main function? What purpose does this serve?

2 Answers

This behavior is part of Rust's core feature of ownership and borrowing, which is the mechanic that provides Rust's memory safety guarantees.

It's purpose is to ensure memory management without requiring GC. The model Rust uses is Ownership-based, so all objects can have one owner only. Now, there are 3 ways of using a variable based on this, either you give up ownership of the variable, let the variable be borrowed immutably or let it be mutable borrowed. It is to ensure proper memory management based on need. If you know you will not use the variable again, you can transfer its ownership and the old value gets dropped. If you know you will use the variable, you can borrow it (mutably or immutably, based on your need). So, you won't be having unused variables and it makes you thin =k about memory management properly, helping you fix some problems that might occur later.

In your example, your code indicates to the compiler that you don't want to use the variable anymore in the main function, this is by the design of the language itself. Remember, the compiler can perform 3 different things (move, borrow and mutable borrow), hence the programmer is expected to let the compiler know which option they are choosing.

Related