В показанном коде arr уже защищён копированием: src имеет отдельный backing array. Результат печати — [1] и [1 2 3]; локальное расширение src в foo не меняет длину src в main.
Как сохранить исходный слайс без изменений при использовании append
В показанном коде 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], поэтому для полной независимости нужна копия.