Sobes.tech
Back to questions
Senior
2

// что выведется на каждом принте? 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) // }

Companies where asked
Холодильник.руХолодильник.ру

Answer from AI

sobes.tech AI

Разберём код пошагово:

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)
    }
    fn(a[:3])
    fmt.Println(a)  // 3-й принт
}
  1. В main создаётся слайс a с длиной 4 и ёмкостью 5: [0,1,2,3].
  2. Вызов fn(a[:3]) передаёт срез из первых трёх элементов: [0,1,2].

Внутри fn:

  • a[2] = 5 изменяет третий элемент с 2 на 5, теперь a внутри функции: [0,1,5].
  • a = append(a, 6) добавляет 6. Ёмкость была 5, длина 3, значит добавление не вызывает аллокацию, слайс расширяется до [0,1,5,6] и ссылается на тот же underlying array, что и исходный слайс.
  • Первый fmt.Println(a) выведет: [0 1 5 6].

Далее:

  • a = append(a, 7) добавляет 7. Теперь длина 5, ёмкость 5, при добавлении происходит выделение нового массива, копирование данных и a внутри функции теперь указывает на новый массив: [0,1,5,6,7].
  • a[0] = 5 меняет первый элемент на 5, теперь a внутри функции: [5,1,5,6,7].
  • Второй fmt.Println(a) выведет: [5 1 5 6 7].

После выхода из функции:

  • В main слайс a остался без изменений после первого append, потому что второй append внутри функции создал новый массив.
  • Но a[2] был изменён на 5 (потому что первый append не создал новый массив, изменения отражаются на исходном массиве).

Третий fmt.Println(a) выведет: [0 1 5 3].

Итог:

[0 1 5 6]
[5 1 5 6 7]
[0 1 5 3]

Объяснение:

  • Первый append не вызывает копирования, изменения отражаются на исходном массиве.
  • Второй append вызывает копирование, изменения после него не влияют на исходный слайс.
  • Изменение a[2] до первого append меняет исходный массив.
  • Изменение a[0] после второго append влияет только на локальный слайс внутри функции.