Difference between these three functions

Imagine the following three functions

fn version_1<T>( a:Vec<T> ,b:Vec<T>) -> (Vec<T> ,Vec<T> ) {
   // Do Something Here 

fn version_2<T>( a:&Vec<T> ,b:&Vec<T>) {
   // Do Something Here 

fn version_3<T>(a:&mut Vec<T> ,b:&mut Vec<T> ) {
   // Do Something Here 

Can i always transform functions like version_3 and version_2 into version_1?
Do they compile to same thing?
What are the performance implications?

There are no "performance implications" per se. Passing stuff around by value is very cheap (a memcpy that is usually optimized away).

Anyway, performance of your code will not depend on how you pass function arguments unless you are doing something seriously sketchy. So instead of worrying ablut performance in imaginary, overly general cases, just start by writing the function that expresses your intent the best.


Not without further implications. If I only have a &Vec<T> and not a Vec<T>, I can't call your version_1 or version_3 without cloning. I can call version_2 with two references to the same Vec, but can't do that with version_1 or version_3.

Rust references are pointer-like, full-fledged types with values that get passed around, and not just a calling convention, in case you didn't know.

The most correct answer is sometimes yes, sometimes no; can vary by program, can vary by call site. (If you're only talking about calling convention that's especially true.)

But the practical answer is that you wouldn't take the &mut unless you needed to mutate and wouldn't take ownership if you didn't need that for some reason, so functions with those signatures will be doing different things in the first place.

Nothing worth thinking about without a very good and specific reason to do so.