Корректировка поведения срезов в Go

Указатель на слайс сохраняет новую длину src, но не отделяет его массив от arr. В данном коде вывод будет [1 5] и [1 5 3], поэтому комментарий об неизменности arr неверен.

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

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

Указатель на слайс сохраняет новую длину src, но не отделяет его массив от arr. В данном коде вывод будет [1 5] и [1 5 3], поэтому комментарий об неизменности arr неверен.

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

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

Условие

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

package main

import "fmt"

func foo(src *[]int) {
 *src = append(*src, 5)
}

func main() {
 arr := []int{1, 2, 3}
 src := arr[:1]

 foo(&src)

 fmt.Println(src) // [1 5]
 fmt.Println(arr) // [1 2 3] — arr не изменяется, так как src отрезан от него
}

Ответ

Указатель на слайс сохраняет новую длину src, но не отделяет его массив от arr. В данном коде вывод будет [1 5] и [1 5 3], поэтому комментарий об неизменности arr неверен.

foo уже корректно обновляет заголовок через *src. Если требуется ещё и сохранить arr, создайте src := append([]int(nil), arr[:1]...) либо для защиты от данного append используйте src := arr[:1:1]. Идиоматичная альтернатива указателю — func foo(src []int) []int { return append(src, 5) } с присваиванием результата в main.

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

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

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

Подробнее