Sobes.tech
Senior

// What will be printed on each print? func fn(a []int) { a[2] = 5 a = append(a, 6) fmt.Println(a) // a = append(a, 7) a[0] = 5 fmt.Println(a) // } func main() { a := make([]int, 0, 5) for i := 0; i < 4; i++ { a = append(a, i) } fn(a[:3]) fmt.Println(a) // }

sobes.tech AI

Answer from AI

Let's analyze the code step by step.

func fn(a []int) {
    a[2] = 5
    a = append(a, 6)

    fmt.Println(a) // 1

    a = append(a, 7)

    a[0] = 5

    fmt.Println(a) // 2
}

func main() {
    a := make([]int, 0, 5)
    for i := 0; i < 4; i++ {
        a = append(a, i) // a = [0,1,2,3]
    }

    fn(a[:3])

    fmt.Println(a) // 3
}
  • In main, a slice a is created with capacity 5 and length 4: [0,1,2,3].
  • The slice a[:3] — the first three elements: [0,1,2], has a capacity of 5 - 0 = 5 (sliced from the beginning).

Inside fn:

  1. a[2] = 5 — changes the third element to 5, so a inside fn: [0,1,5].
  2. a = append(a, 6) — adds 6. Since capacity allows, append modifies the original array, so a inside fn: [0,1,5,6].
  3. fmt.Println(a) — outputs [0 1 5 6].
  4. a = append(a, 7) — adds 7, so a inside fn: [0,1,5,6,7].
  5. a[0] = 5 — changes the first element to 5, so a inside fn: [5,1,5,6,7].
  6. fmt.Println(a) — outputs [5 1 5 6 7].

After fn returns:

  • In main, the slice a was [0,1,2,3].
  • Changes through a[2] = 5 and the first append inside fn affected the original array because capacity allowed extension without copying.
  • But the second append (a = append(a,7)) possibly caused reallocation, so subsequent changes did not affect the original slice.

Let's check what changed in main:

  • a in main after fn: [0,1,5,3] — the third element changed to 5 (from a[2] = 5 inside fn).

Final outputs:

  1. First fmt.Println(a) in fn: [0 1 5 6]
  2. Second fmt.Println(a) in fn: [5 1 5 6 7]
  3. fmt.Println(a) in main: [0 1 5 3]

Explanation:

  • Changes to slice elements affect the original array.
  • Append, if it does not exceed capacity, extends the slice on the same array.
  • If append causes reallocation, the slice inside the function points to a new array, and changes do not reflect outside.

Thus, changes after the second append do not affect the original slice in main.