Insert An Element At A Position In
Fast recall
Quick revision
Core answer
Practical understanding of Slice Tricks.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
The one-liner composes two appends: build a temp slice holding the new element plus the tail, then overwrite the shifted region:
s := []int{1, 2, 3, 4}
i := 2
s = append(s[:i], append([]int{99}, s[i:]...)...)
// s is [1 2 99 3 4]It reads inside-out: s[i:] is [3 4]; append([]int{99}, that...) is [99 3 4]; appending that onto s[:2] ([1 2]) gives [1 2 99 3 4]. Correct, and the standard reference form — but it allocates a temp slice for the tail, so the cost is a copy plus garbage.
The allocation-free version does what the runtime would: grow once, shift the tail right by one, store the element:
s = append(s, 0) // grow by one (zero value at end)
copy(s[i+1:], s[i:]) // shift tail right
s[i] = 99 // place the elementcopy handles the overlapping move correctly (it's defined for overlap). Same result, one allocation, no temp. When insertion is in a hot path, the three-step version is the one to write; the one-liner is the one to remember.
Insert An Element At A Position In
Direct Answer
s = append(s[:i], append([]T{x}, s[i:]...)...) — or the manual grow-shift for zero extra allocation.
Deep Dive & Architecture
The one-liner is compositional — two appends — and each append does what append always does:
s = append(s[:i], append([]T{x}, s[i:]...)...)
Inner: append([]T{x}, tail...) — a fresh slice with capacity for exactly one, immediately exceeded — so it takes the allocate path: new array holding [x, tail...]. Outer: append(prefix, that...) — copies that onto s at i, sliding everything right.
It allocates because the INNER append starts from a fresh []T{x} with no room. That's the whole difference from the manual version:
s = append(s, zero) // one growth if at cap
copy(s[i+1:], s[i:]) // right-shift the tail — copy handles overlap
s[i] = x
No temp slice — the shift happens inside s's own storage. The copy-overlap subtlety: Go's copy behaves as if copying through a temp when regions overlap, so a right-shift in one call is correct (a forward copy would otherwise clobber the tail before it's read).
Cost comparison at the same final state: one-liner = 1 temp allocation + 2 copies; manual = 1 capacity check + 1 overlapping copy. The manual version is what you write when the insert is in a loop (parsers, buffers); the one-liner is what you write once, where clarity dominates.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Slice Tricks, and when would you use it?
- How would you compare Slice Tricks with an alternative?
- What is a common mistake when using Slice Tricks?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.