Go

Deleting from a slice in place: what do both lines print?

Question 512HardGo 1.22 to 1.25
s := []int{1, 2, 3, 4, 5}
t := append(s[:1], s[3:]...)
fmt.Println(t, s)

u := []int{1, 2, 3, 4, 5}
v := slices.Delete(u, 1, 3)
fmt.Println(v, u)

Output:

[1 4 5] [1 4 5 4 5]
[1 4 5] [1 4 5 0 0]

s[:1] has length 1 but capacity 5, so append writes 4 and 5 into indices 1 and 2 of the same array. t looks right, but s (and every other slice that shares that array) now holds [1 4 5 4 5]. The stale tail values are still there.

slices.Delete does the same shift, but since Go 1.22 it also zeroes the elements between the new length and the old length. That is why u ends in 0 0. The zeroing lets the garbage collector free pointers held in the dropped tail (for example in a []*Conn), and it makes stale aliases easy to spot. slices.Compact, slices.DeleteFunc, and slices.Replace clear the tail in the same way.

Code-review rule: after an in-place delete, use only the returned slice (s = slices.Delete(s, i, j)) and treat every older header over the same array as invalid. If callers must keep the original, clone it first.

More on Tricky Output & Code-Review Puzzles

All 38 Tricky Output & Code-Review Puzzles questions