183. std::mem::take — Move Out of &mut self Without the Clone
You need the Vec out of &mut self, the borrow checker says no, so you .clone() it. Don’t. mem::take swaps in the default and hands you the original — zero allocation.
The borrow checker won’t let you move a field out of &mut self, because that would leave self half-initialized. The usual workarounds are ugly: clone the whole thing, or refactor the API to take self by value.
std::mem::take does the right thing in one line. It replaces the field with T::default() and returns the old value. For collections, Default is empty — so there’s no allocation, just a pointer swap.
| |
Where it really earns its keep is state-machine transitions, where you need to consume the data inside the current variant before swapping the variant:
| |
Without mem::take, that pattern usually devolves into a mem::replace(self, Stream::Done) and a match on the returned value. mem::take is shorter and reads top-to-bottom.
It works for any T: Default — String, HashMap, Option, Box<[T]>, your own structs that derive Default. If Default isn’t free for your type, reach for mem::replace and pass the sentinel you actually want.