Общий массив слайсов Go: перезапись элемента через append

После modifySlice длина s остаётся 2, но общий массив содержит 0, 0, 3. Затем append(s, 4) перезапишет третий элемент, и s станет [0 0 4].

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

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

После modifySlice длина s остаётся 2, но общий массив содержит 0, 0, 3. Затем append(s, 4) перезапишет третий элемент, и s станет [0 0 4].

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

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

Условие

func TestSlice(t *testing.T) { s := make([]any, 0, 10) s = append(s, 1, 2)

modifySlice(s, 3)
log.Printf("1: %+v", s)

sPtr := unsafe.Pointer(unsafe.SliceData(s))
a := (*[10]any)(sPtr)
log.Printf("2: %+v", *a)

s = append(s, 4)
log.Printf("3: %+v", s)

}

func modifySlice(s []any, v any) { s = append(s, v) s[0] = 0 s[1] = 0 }

Ответ

После modifySlice длина s остаётся 2, но общий массив содержит 0, 0, 3. Затем append(s, 4) перезапишет третий элемент, и s станет [0 0 4].

Без префикса времени log.Printf выведет:

1: [0 0]
2: [0 0 3 <nil> <nil> <nil> <nil> <nil> <nil> <nil>]
3: [0 0 4]

В функцию передаётся копия заголовка slice. Capacity 10 хватает для append, поэтому новый массив не выделяется, а изменения первых двух элементов видны вызывающему коду. Новый len=3 остаётся локальным. Для просмотра массива в этой задаче unsafe не нужен: s[:cap(s)] даёт тот же доступ в пределах capacity безопасным способом.

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

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

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

Подробнее