241. slice::split_first — Peel the Head Off a Slice, Keep the Tail, No Indexing
slice[0] panics on an empty slice, and &slice[1..] is a second chance to get the bounds wrong. split_first hands you the head and the tail together — or None if there’s nothing there — so the empty case is a pattern, not a panic.
The manual head-and-tail
Reach for the first element and the rest, and you write two indexing operations that both assume the slice is non-empty:
| |
The bounds check is real, but it’s on you to remember the is_empty guard. Drop it and an empty slice panics at runtime.
split_first gives you both, safely
| |
split_first returns Option<(&T, &[T])>: the first element and a slice of everything after it, or None when the slice is empty. The empty case can’t be forgotten — it’s a variant you have to match.
split_last peels from the other end
| |
Same shape, mirrored: the last element plus everything before it.
Where it shines: recursion without index math
Because the tail is just another slice, split_first makes structural recursion clean — the base case is None, and there’s no i + 1 to fumble:
| |
Need to mutate as you walk? split_first_mut and split_last_mut return (&mut T, &mut [T]), so you can edit the head and recurse into the tail without a borrow fight. Whenever you catch yourself pairing slice[0] with &slice[1..], this is the method that folds both — and the empty check — into one.