What do the cap print and the post-append x and y lines show here?
Give the printed capacities, then trace how append(y, "z") affects x and y.
func slicesSharedMemAppend() {
x := []string{"a", "b", "c", "d"}
y := x[:2]
fmt.Println(cap(x), cap(y))
y = append(y, "z")
fmt.Println("x:", x)
fmt.Println("y:", y)
}
Predict the output.
It prints 4 4, then x: [a b z d] and y: [a b z]. y := x[:2] has len 2 but inherits cap 4 to the end of x's backing array, so append(y, "z") has spare room and writes into the shared x[2], overwriting c instead of allocating.
- ✗Thinking
cap(y)is 2 — a reslice inherits capacity to the end of the parent's array, so it is 4 - ✗Assuming
appendalways allocates — with spare cap it overwrites the shared element in place - ✗Forgetting that
x's length is unchanged — onlyx[2]'s value flips toz
- →How would
y := x[:2:2]changecap(y)and the result of theappend? - →Why does
x's length stay 4 even thoughx[2]was overwritten?
What does this code print?
x := []string{"a", "b", "c", "d"}
y := x[:2]
fmt.Println(cap(x), cap(y))
y = append(y, "z")
Output
4 4
x: [a b z d]
y: [a b z]
Why append corrupts x
y := x[:2] has len 2, but its capacity is inherited to the end of x's backing array: cap(y) == 4. So the first line prints 4 4.
append(y, "z") has spare room (len 2 < cap 4), so it does not allocate — it writes "z" into the shared backing array at index 2, overwriting x[2] (was c). The length of x is unchanged (its header is separate), but the value at x[2] is now z → x = [a b z d]. The returned y has len 3: [a b z].
To force append to allocate and leave x alone, cap the capacity with a full-slice expression: y := x[:2:2] (then cap(y) == 2). </content>