Влияние вызова append внутри функции на исходный срез

Будет напечатано [1], затем [1 5 3]: append меняет общий backing array, но длина исходного src остаётся равной 1.

Короткий ответ

Что ответить на собеседовании

Будет напечатано [1], затем [1 5 3]: append меняет общий backing array, но длина исходного src остаётся равной 1.

Подробный разбор

Ответ с пояснениями

Условие

Нужно понять, как изменение среза src с помощью операции append внутри функции отразится на массиве‑источнике arr, который был использован для создания src.

package main

import "fmt"

func foo(src []int) {
    src = append(src, 5)
}

func main() {
    arr := []int{1, 2, 3}
    src := arr[:1]

    foo(src)

    fmt.Println(src)
    fmt.Println(arr)
}

Ответ

Будет напечатано [1], затем [1 5 3]: append меняет общий backing array, но длина исходного src остаётся равной 1.

В функцию передаётся копия дескриптора среза: указатель на массив, длина и вместимость. Для src вместимость равна 3, поэтому добавление 5 не требует нового массива и записывает значение в arr[1].

Новая длина 2 сохраняется только в локальной переменной функции. Чтобы запретить append использовать хвост исходного массива, можно передать src[:len(src):len(src)]; если нужна независимость и при изменении существующих элементов, необходима копия данных.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее