Первый вывод — [1 2]: append внутри modifySlice выделяет новый массив, потому что len и cap равны 2. Чтение затем через *[10]any выходит за выделенный массив и небезопасно.
Append с новым массивом и небезопасное чтение через unsafe
Первый вывод — [1 2]: append внутри modifySlice выделяет новый массив, потому что len и cap равны 2. Чтение затем через *[10]any выходит за выделенный массив и небезопасно.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
func TestSlice(t *testing.T) { s := make([]any, 0, 2) s = append(s, 1, 2) // 1 2 len(2) cap(2)
modifySlice(s, 3)
log.Printf("1: %+v", s)
sPtr := unsafe.Pointer(unsafe.SliceData(s))
a := (*[10]any)(sPtr)
log.Printf("2: %+v", *a) // 0 0 3 <nil>....
s = append(s, 4)
log.Printf("3: %+v", s) // 0 0 4
}
func modifySlice(s []any, v any) { s = append(s, v) s[0] = 0 s[1] = 0 }
Ответ
Первый вывод — [1 2]: append внутри modifySlice выделяет новый массив, потому что len и cap равны 2. Чтение затем через *[10]any выходит за выделенный массив и небезопасно.
После такого unsafe-чтения корректный дальнейший вывод гарантировать нельзя: возможны авария и произвольные данные. Если удалить unsafe-блок, последний append даст [1 2 4]. Изменения нулевых элементов происходили в новом локальном массиве modifySlice, поэтому комментарии [0 0 ...] неверны. Читать десять элементов из массива на два элемента нельзя.