1
votes

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
For one thing, so that the function has the option to destroy it without worrying about whether the caller still has references to it. - Nate Eldredge
What's the alternative? Pass-by-value and pass-by-reference are often thought of in terms of ownership. If you've transferred ownership of a value into a function, what value does the original variable have? - kmdreko

2 Answers

1
votes

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

1
votes

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.