Как сохранить исходный слайс без изменений при использовании append

В показанном коде arr уже защищён копированием: src имеет отдельный backing array. Результат печати — [1] и [1 2 3]; локальное расширение src в foo не меняет длину src в main.

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

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

В показанном коде arr уже защищён копированием: src имеет отдельный backing array. Результат печати — [1] и [1 2 3]; локальное расширение src в foo не меняет длину src в main.

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

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

Условие

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

package main

import "fmt"

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

func main() {
    arr := []int{1, 2, 3} // len 3, cap 3
    src := append([]int(nil), arr[:1]...) // len 1, cap 1 — скопировать слайс

    foo(src)

    fmt.Println(src) // 1
    fmt.Println(arr) // 1 2 3
}

Ответ

В показанном коде arr уже защищён копированием: src имеет отдельный backing array. Результат печати — [1] и [1 2 3]; локальное расширение src в foo не меняет длину src в main.

Копирование выполняет append([]int(nil), arr[:1]...). Точная capacity новой копии не гарантируется равной единице, но с arr она память не делит. Если нужно защититься только от дописывания, можно передать arr[:1:1]: append выделит другой массив. Это не защищает от прямой записи src[0], поэтому для полной независимости нужна копия.

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

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

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

Подробнее