147. Cell::as_array_of_cells — Mutate One Slot of a Cell-Wrapped Array
You have a Cell<[i32; 4]> and you want to bump element [2]. cell.get(), mutate the copy, cell.set(...) the whole thing back — for one slot? Cell::as_array_of_cells hands you &[Cell<i32>; 4] so each slot is its own little Cell.
The setup
Cell<T> gives you interior mutability for Copy types: &Cell<T> lets you swap the inner value through a shared reference. That’s lovely for a scalar, but the moment T is an array it becomes awkward — Cell only exposes get() and set() for the entire T:
| |
Three lines and a full-array copy in each direction — just to add 1. It also doesn’t compose: if you wanted to hand a single slot to another function, you’d have to pass the whole Cell<[i32; 4]> plus an index, and trust the callee to put the array back.
Enter as_array_of_cells
Stabilized in Rust 1.91, Cell::as_array_of_cells reinterprets &Cell<[T; N]> as &[Cell<T>; N]:
| |
No copy, no set of the whole array. The cast is free at runtime — Cell<T> is #[repr(transparent)] over T, so a Cell<[T; N]> and a [Cell<T>; N] have identical layout. The standard library just gives you the safe view of that fact.
Pair it with Cell::update
Cell::update is the obvious dance partner — read-modify-write in one call, on a single slot:
| |
That’s the loop you actually wanted. No RefCell, no runtime borrow check, no panic risk.
Hand out a single slot
Because each element is a real &Cell<T>, you can pass one slot to another function and let it mutate just that slot — the rest of the array is untouched and the caller keeps full access:
| |
Try expressing that with cell.get() / cell.set() — you can’t, not without rebuilding the array on every call.
Slices too
There’s a sibling for unsized arrays: Cell::as_slice_of_cells turns &Cell<[T]> into &[Cell<T>]. Useful when the length isn’t known at compile time:
| |
And as of Rust 1.95, both views also implement AsRef, so generic code can take impl AsRef<[Cell<T>]> and accept either form.
The signatures
| |
Both are zero-cost reinterpretations — pure type-system moves, no copying. Reach for them any time you find yourself doing the get / mutate / set two-step on a Cell that wraps a collection.