Исследование поведения slice и функции append

Все три Println покажут [0 1 2 3] 4 5. Первый append создаёт другой массив, второй меняет скрытый пятый элемент общего массива.

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

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

Все три Println покажут [0 1 2 3] 4 5. Первый append создаёт другой массив, второй меняет скрытый пятый элемент общего массива.

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

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

Условие

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

package main

import "fmt"

func main() {
 slice := make([]string, 0, 5)
 slice = append(slice, "0")
 slice = append(slice, "1")
 slice = append(slice, "2")
 slice = append(slice, "3")
 fmt.Println(slice, len(slice), cap(slice)) // ?

 addToSlice1(slice)
 fmt.Println(slice, len(slice), cap(slice)) // ?

 addToSlice2(slice)
 fmt.Println(slice, len(slice), cap(slice)) // ?
}

func addToSlice1(slice []string) {
 slice = append(slice[:1:1], "one")
}

func addToSlice2(slice []string) {
 slice = append(slice, "two")
}

Ответ

Все три Println покажут [0 1 2 3] 4 5. Первый append создаёт другой массив, второй меняет скрытый пятый элемент общего массива.

В addToSlice1 выражение slice[:1:1] ограничивает вместимость единицей. Добавление one требует нового массива и не затрагивает исходные элементы.

В addToSlice2 свободная вместимость есть: two записывается по индексу 4 общего массива. Внешняя длина остаётся 4, поэтому печать не показывает этот элемент. После второго вызова fmt.Println(slice[:5]) показал бы [0 1 2 3 two]. Копируется дескриптор среза, а не все данные.

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

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

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

Подробнее