Does assigning the result of Iterator::collect() to a Vec reallocate?

Suppose I have a Vec and I want to replace it with the contents of an iterator:

let mut v = vec![0, 1, 2, 3];
v = (0..4).map(|x| x * x).collect();

If the original Vec already had enough capacity allocated, will it reuse its memory, or does the buffer containing [0, 1, 2, 3] get freed and a new buffer allocated for the result of Iterator::collect()?

1 Like

It will get freed and a new buffer will be allocated. The = assignment is always "dumb" and will just replace the old value with the new one.

To achieve a memory reuse in this case, you can use clear + extend:

v.clear();
v.extend((0..4).map(|x| x * x));

See also the (existing) clone_from and (proposed) collect_into (huh, the PR seems closed, not sure what's the status on that).

5 Likes

To expand on the previous comment, note that the clear method promises not to change the allocated capacity of the vector.

1 Like

Thanks @krdln, this is what I suspected, but I wasn't sure.

1 Like

Another thing for the list (though unstable and not relevant for iterators): ToOwned::clone_into, for writing a slice into an existing Vec.

1 Like