Поведение срезов при использовании append в Go

Обычно программа выводит [1 2 3 5] [1 2 3 5]: оба слайса разделяют массив с запасом capacity, и последний append перезаписывает четвёртый элемент.

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

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

Обычно программа выводит [1 2 3 5] [1 2 3 5]: оба слайса разделяют массив с запасом capacity, и последний append перезаписывает четвёртый элемент.

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

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

Условие

Определите, какой результат будет напечатан программой ниже. Нужно выяснить, изменяется ли второй срез после модификаций первого – то есть, происходит ли совместное использование внутреннего массива или создаётся отдельная копия.

package main

import "fmt"

func main() {
    var sliceA []int
    var sliceB []int

    sliceA = append(sliceA, 1)
    sliceA = append(sliceA, 2)
    sliceA = append(sliceA, 3)
    sliceB = append(sliceA, 4)
    sliceA = append(sliceA, 5)

    fmt.Println(sliceA, sliceB) // ?
}

Ответ

Обычно программа выводит [1 2 3 5] [1 2 3 5]: оба слайса разделяют массив с запасом capacity, и последний append перезаписывает четвёртый элемент.

sliceB получает увеличенную длину, но sliceA после этого всё ещё имеет длину 3. Его следующий append пишет на ту же позицию. Точный рост capacity реализация не обещает: если после первых трёх элементов места не осталось, массивы будут раздельными и sliceB закончится на 4. Для гарантированной независимости явно копируйте исходный слайс.

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

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

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

Подробнее