230. slice::split_at_mut — Two Mutable Halves, No unsafe, No Borrow Fight
Need a &mut to two different elements of the same slice at once? Indexing twice won’t compile — the borrow checker sees the whole slice borrowed twice. split_at_mut hands you two non-overlapping mutable halves instead.
The borrow checker says no
You want to mutate two elements of a slice in the same expression — say, swap-style logic that reads one and writes another:
| |
The compiler can’t prove v[0] and v[3] are different elements, so it rejects two overlapping &mut borrows of v. Both indexing operations borrow the entire slice.
split_at_mut gives you two disjoint slices
split_at_mut(mid) splits a slice into [0, mid) and [mid, len), returning a &mut to each. Because the halves provably don’t overlap, the borrow checker is happy:
| |
Internally it’s one bounds check and a pointer offset — no copying, no allocation. It panics only if mid > len; use split_at_mut_checked to get an Option instead.
Where it shines: in-place algorithms
Reversing a slice by hand needs a read and a write to two indices each step. Split once, walk inward:
| |
The two iterators borrow disjoint halves, so iterating both mutably at once just works.
Divide and conquer for free
Because each half is itself a &mut [T], recursive algorithms split cleanly — the basis for parallelizing with something like Rayon’s join:
| |
Whenever you’re fighting the borrow checker over two mutable spots in one slice, stop reaching for unsafe — split_at_mut is the safe, zero-cost answer. For non-adjacent individual elements, its cousin get_disjoint_mut does the same trick by index.