184. Option::take — The Ergonomic Sibling of mem::take, Just for Option
You’ve got an Option<T> behind &mut self and you need the T out. mem::take works, but the field is already an Option — .take() reads better and does the same job.
This morning’s bite on std::mem::take covered the general move: swap in T::default(), hand back the original. For Option<T>, the default is None — and the standard library exposes that exact operation as Option::take, so the call site stops looking like memory plumbing:
| |
Internally Option::take is one line: mem::replace(self, None). The win is purely about the call site.
The pattern earns its keep in Drop, where you need to consume an owned resource by value but only have &mut self:
| |
Without .take(), you can’t move self.join out (you only have &mut self), and JoinHandle::join takes self by value — so you’re stuck. take() swaps None in and gives you the owned JoinHandle to consume.
It also kills the classic “transfer once” pattern in builders and state machines:
| |
Reach for Option::take whenever the field is already Option<T>. Reach for std::mem::take when the field is some other T: Default and you want the empty version left behind.