115. Vec::resize_with — Grow a Vec With a Closure, Not a Clone
Vec::resize makes every new slot a clone of the same value. When you need fresh values per slot — counters, allocations, defaults — resize_with calls a closure for each new element instead.
Vec::resize(n, value) is fine when the filler is cheap and identical, but it has two annoyances. It needs T: Clone, and every new slot is the same clone. So this doesn’t work the way you want:
| |
That one happens to be safe because Vec::clone actually allocates. But the moment your T is Rc<RefCell<…>>, every slot points at the same cell. And if T isn’t Clone at all, you can’t call resize in the first place.
resize_with takes a closure and calls it once per new slot:
| |
The closure can capture mutable state, so each call is fresh. Generating IDs, pulling from an RNG, allocating independent buffers — all easy:
| |
For non-Clone types, Default::default is the usual filler:
| |
Shrinking still works, and the closure is never called when the new length is smaller:
| |
Reach for resize_with whenever the filler isn’t a single static value — and especially when T doesn’t (or shouldn’t) implement Clone.