105. Vec::extend_from_within — Duplicate a Range Without Fighting the Borrow Checker
Trying to copy a slice of a Vec back onto the end of itself? v.extend_from_slice(&v[..k]) won’t compile — &v and &mut v collide. extend_from_within is the one-call answer.
The borrow checker says no
It looks innocent: take the first few bytes of a buffer and append them to the end. The naïve write doesn’t even reach the type checker without complaint:
| |
extend_from_slice needs &mut self, and &buf[..2] is an immutable borrow of the same Vec. Two borrows, one of them mutable, same value — instant rejection.
The usual workarounds bloat the call site. Either make a temporary copy, or reach for unsafe and a raw pointer dance:
| |
A whole heap allocation just to copy two bytes inside a vector you already own. There’s a better way.
extend_from_within — one call, no temp
Vec::extend_from_within takes a range into self and appends those elements. No second buffer, no unsafe, no fight with the borrow checker:
| |
It accepts any RangeBounds<usize> — ..k, i..j, i..=j, .. — so you can grab whatever slice you want, including the whole Vec:
| |
It requires T: Clone, and clones each element exactly once. For Copy types like primitives it lowers to a single memcpy.
A real use: building patterns
It’s especially nice for building repeating or growing patterns where each step depends on the previous one — think DSP buffers, simple test fixtures, or doubling tricks:
| |
When to reach for it
Any time you’d write v.extend_from_slice(&v[range]) and the borrow checker stops you, swap in v.extend_from_within(range). Stable since Rust 1.53, exists for both Vec<T> and VecDeque<T>, and quietly turns a frustrating compile error into a one-liner.