I am trying to learn the ins and outs of memory in Rust. When a vector is created inside a function and then returned, is a reference returned or is the entire vector copied?
Example:
use std::io;
fn line_to_ints() -> Vec<u32> {
let mut line = String::new();
io::stdin()
.read_line(&mut line)
.expect("Failed to read line");
return line
.split(" ")
.map(|x| x.parse().expect("Not an integer!"))
.collect();
}
Will the return behavior here also be the same for all other non-primitive data types?
Unlike Is there any way to return a reference to a variable created in a function?, I would like to know a bit more about what is happening under the hood. The answers to that question do not provide clarity as to whether or not the vector is created and then copied to a new location, or ownership of the pointer is returned I understand vectors are created on the heap so I imagine a pointer is involved.
is a reference returned
No. It cannot be because there's nothing to reference once the function ends. This is covered in detail in Is there any way to return a reference to a variable created in a function?.
is the entire vector copied
Yes, but probably not how you mean it. A Vec
is basically defined as
struct Vec<T> {
capacity: usize,
length: usize,
data: *mut T,
}
Semantically, these 3 pointer-sized fields are moved from the function to the caller. The N elements contained by the vector are not copied.
Implementation-wise, the compiler/optimizer can pick from a large bag of tricks:
The only way to know which it picks is to look at the MIR / LLVM IR / assembly.
Will the return behavior here also be the same for all other non-primitive data types?
Yes. Rust's data types are all treated the same. Primitive vs. non-primitive means nothing for the semantics of the language.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With