97. Option::take_if — Take the Value Out Only When You Want To
You want to pull a value out of an Option — but only if it meets some condition. Before take_if, that little sentence turned into a five-line dance with as_ref, is_some_and, and a separate take(). Now it’s one call.
The old dance
Say you hold an Option<Session> and you want to evict it if it’s expired, otherwise leave it alone. The naive version keeps ownership juggling in your face:
| |
Three lines of control flow just to express “take it if it’s stale.” And if you ever need to inspect the value more deeply, you’re one borrow-checker nudge away from rewriting the whole thing.
Enter take_if
Option::take_if bakes the whole pattern into one method — it runs your predicate on the inner value, and if the predicate returns true, it take()s it for you:
| |
One line, one branch, one name for the pattern.
The mutable twist
Here’s the detail that trips people up: the predicate receives &mut T, not &T. You can mutate the inner value before deciding whether to yank it:
| |
Useful for cache eviction with hit counters, retry-until-exhausted slots, or anywhere “inspect, maybe mutate, maybe remove” shows up. Reach for take_if whenever you find yourself writing if condition { x.take() } else { None }.