I am starting to learn Rust. In a lot of examples I have come across so far, I have noticed that functions are often implemented to return variables by value even if they are of a complex data type like a struct. This seems to be especially true for the idiomatic constructor functions new like in this example from Listing 12-7 of the Rust book (new returns a complex data type Config):
fn main() { let args: Vec<String> = env::args().collect(); let config = Config::new(&args); // --snip--}// --snip--impl Config { fn new(args: &[String]) -> Config { let query = args[1].clone(); let file_path = args[2].clone(); Config { query, file_path } }}Having a bit of C++ experience, I know that it is more efficient to handle complex data types by reference (if the complex type is bigger than a pointer). I.e., the calling context is in charge of setting up the variable and only passes an address / a reference of it to the function as a so called output parameter. The function then writes the data directly to the variable.
I have come across this blog post dealing with this exact topic. One of the arguments for returning by value raised in the post is:
[Using an] out parameter is a performance optimization that you as a programmer do by hand[.]
and
[O]ptimizations can be done by the compiler[.]
This other question and this reddit post also seem to indicate that one should return by value and the compiler will deal with making it efficient.
I understand that this sort of optimization is called Return Value Optimization (RVO) and it also exists for C++ compilers. However, as far as I know, it is far from normal for C++ code to return by value and expect the compiler to make it as efficient as possible.
So, my question is: "Why is it idiomatic in Rust to return by value and thus rely on compiler optimzations?" Is there a rule that I as a programmer can memorize to know when returning by value is 100 % fine and will be optimized? If not, I would rather swallow the pill of using an output parameter to be sure that my code is efficient which seems to be the norm for C++ programs.