When you're writing (or read someone else's) functions, you should be considering three types of parameters:
* (&) borrowed
* (mut &) mutably borrowed
* () moved
The borrow operator should be your default/go-to decoration. Don't use the more destructive exchanges until the compiler forces you to. As I write this out, I'm thinking this might be a small short-coming in Rust's design. I.e., read/borrowed should maybe be the default/undecorated behavior and special pains should be required to move a reference.Anyway, borrowed means, "I just wanna read some stuff off of that. I promise not to change a thing!"
Mutable borrowing means, "Gimme that--I'm going to change it! Expect it to differ as part of the output of this function."
Moving means, "That's mine now! I'm going to wreck it beyond any usage you'd try to do after I'm done. If you think you still want it, better hand me a clone."
It might also be good to spend some time working through the book if you haven't already: https://doc.rust-lang.org/stable/book/
Here're some HN comments about advanced patterns:
* https://news.ycombinator.com/item?id=13470592#13470904
* https://news.ycombinator.com/item?id=13470975
* Also recommends http://cglab.ca/~abeinges/blah/too-many-lists/book/