What do the three Println lines print after these appends?
Two overlapping slices are passed to a function that appends to each. Determine the three printed lines and explain why the caller's array and slices are (or are not) affected.
func main() {
arr := []int{1, 2, 3, 4, 5}
slice1 := arr[1:] // {2,3,4,5} len=4 cap=4
slice2 := slice1[1:3] // {3,4} len=2 cap=3
ModifySlice(slice1)
ModifySlice(slice2)
fmt.Println("Original array:", arr) // ?
fmt.Println("Slice1:", slice1) // ?
fmt.Println("Slice2:", slice2) // ?
}
func ModifySlice(slice []int) {
slice = append(slice, 6, 7)
}
Predict the output.
All three print their original values — [1 2 3 4 5], [2 3 4 5], [3 4]. slice1 has cap 4 and slice2 cap 3, so appending two elements overflows both. Each append allocates a fresh backing array and reassigns only the local copy of the header, so the caller's headers and arr never see it.
- ✗Assuming
appendalways mutates the caller's backing array — it only writes in place when there is sparecap - ✗Forgetting that
append's reassignment touches only the local parameter copy of the header, never the caller's variable - ✗Miscomputing
slice2capacity —slice1[1:3]hascap3, not 2, so two appends still overflow
- →If
slice2hadcap4 instead of 3, whichPrintlnline would change and why? - →How would the output differ if
ModifySlicereturned the slice and the caller reassigned it?
What does this code print?
package main
import "fmt"
func main() {
arr := []int{1, 2, 3, 4, 5}
slice1 := arr[1:] // {2,3,4,5} len=4 cap=4
slice2 := slice1[1:3] // {3,4} len=2 cap=3
ModifySlice(slice1)
ModifySlice(slice2)
fmt.Println("Original array:", arr) // ?
fmt.Println("Slice1:", slice1) // ?
fmt.Println("Slice2:", slice2) // ?
}
func ModifySlice(slice []int) {
slice = append(slice, 6, 7) // result assigned to the local parameter
}
Output
Original array: [1 2 3 4 5]
Slice1: [2 3 4 5]
Slice2: [3 4]
Why nothing changed
slice1 points at arr[1] with len=4, cap=4; slice2 points at arr[2] with len=2, cap=3.
Inside ModifySlice, both append calls add two elements and exceed cap:
slice1:len 4 + 2 = 6 > cap 4→ the runtime allocates a new backing array.slice2:len 2 + 2 = 4 > cap 3→ a new backing array too.
append returns a new header, but it is assigned to the parameter slice — a local copy. The caller's header (slice1 / slice2) and the shared arr stay as they were. Because both appends reallocated, not a single element is written into arr.
⚠️ Trap: had there been spare cap, append would have written 6, 7 in place into the shared arr (mutating neighbouring indices), yet the caller's slice variable would still keep its old len. Here both writes went to fresh arrays.