Returning a Vec<enum> -- what does it mean?


#1

Hello Rustaceans,

I am curious about what it means to return a Vec<enum>, as yaml-rust does. Does the vector own the enum values? What is the scope (lifetime) of the vector and its values? Are the enum values heap allocated?

– Wondering About Vectors in SOMA


#2

Yes, because it does not take references(in this particular case).

The scope of the vector(and the values it owns) is the scope where it was declared. It gets dropped automatically when it gets out of scope.

Yes. The vector is allocated on the stack but the values themselves are on the heap.


#3

Thank you for your informative reply.

So the vector is a struct with a size and a heap allocated array of the enums? And I gather the vector is returned by moving (copying) it to a location in the caller’s stack?

Is it possible to recycle the enum values, as when one wishes to return one element of the vector from a function? Is the answer no because the vector owns them?

– Heaps Of Questions in Potrero Hill


#4

I started writing a response in the morning and forgot about it, sorry.

Yes, the short version would be that the vector is a struct that has on the stack(if you don’t allocate it on the heap yourself of course, like putting it in a Box) the size of the pre-allocated memory(not in bytes but in number of elements that can be stored), it’s length(number of actual elements in the vector) and a pointer to the data that is in the heap.
Of course it’s an implementation detail, but the short version is that it contains that data.

When a structure like the vector is moved, what actually happens is that yes, what was on the stack is taken ownership as you understood(a copy is made of those fields that are on the stack before popping it of the current stack) but the data that is in the heap doesn’t need to be copied, it remains there like nothing happened.

I am not sure I understand the question.
If the vector owns the elements, than it can pop elements out freely and return the element that was popped.
If it is a shared reference(immutable reference), than of course you won’t be able to pop any elements and return them.
You can also clone() elements, but it is preferred not to make additional copies if you don’t really need this.

Also remember to use references where appropriate. In Rust it’s pretty nice to use references to be efficient and not worry about safety problems that come with references because Rust guarantees you that you won’t make any mistakes related to pointers/references(in safe code).