Go

What does the caller see after calling modify?

Question 484MediumGo 1.22 to 1.25
func modify(s []int) {
    s[0] = 99
    s = append(s, 4)
    s[1] = 42
}

func main() {
    x := []int{1, 2, 3}    // len 3, cap 3
    modify(x)
    fmt.Println(x)         // ?

    y := make([]int, 3, 4) // len 3, cap 4
    modify(y)
    fmt.Println(y, y[:4])  // ?
}

Output: [99 2 3], then [99 42 0] [99 42 0 4].

A slice is passed as a header (pointer, len, cap) by value. s[0] = 99 writes through the shared pointer, so the caller sees it in both cases.

For x (cap 3), append must reallocate. s now points to a new array, so s[1] = 42 is not visible to the caller. For y (cap 4), append writes in place and s[1] = 42 reaches the shared array. The caller's header still has length 3, though, so the appended 4 is only visible by reslicing to y[:4].

Rule: a function that appends must return the new slice (s = f(s)), as append does, or take a *[]T.

More on Tricky Output & Code-Review Puzzles

All 38 Tricky Output & Code-Review Puzzles questions