Consider the following for-in loop in Rust, which moves the non-privative data type String
.
let strings: Vec<String> = something;
for s in strings {
// uses `s`
}
Since a String is not a bitwise trivially copyable datatype, the elements of strings
are moved, one by one, into s
and then dropped at the end of the block defined by {
and }
.
After each iteration, what does the Vec
object look like?
Imaging that strings
is initialized to contain this:
[ "hello", "world", "final string" ]
After 1 iteration of the loop, the element "hello"
has been moved.
We cannot have a Vec
now looking like this
[ None, "world", "final string" ]
because None
is not a String
.
This means the Vec
must now be shorter:
[ "world", "final string" ]
Since "hello"
was removed from the front of the Vec
this strongly suggests to me that a re-allocation has taken place.
If this is not the case, then why does no re-allocation occur.
AFAIK Vec
does not contain something like an offset to the first element in memory, like a C++ std::deque
would. So it seem to me that Rust Vec
cannot avoid a re-allocation when the first element is moved.
Finally, assuming I have understood all of the above, which may not be the case, does this mean that iterating over a Vec
containing not-copyable objects is slow ?