Срезы Голанга передаются по значению?

В Голанге я пытаюсь сделать функцию среза скремблирования для моей проблемы с коммивояжером. Выполняя это, я заметил, когда я начал редактировать срез, который я дал, функция скремблирования была различной при каждом ее проходе.

После некоторой отладки я узнал, что это связано с тем, что я редактировал фрагмент внутри функции. Но так как Голанг должен быть языком "перевал по значению", как это возможно?

https://play.golang.org/p/mMivoH0TuV

Я предоставил ссылку на детскую площадку, чтобы показать, что я имею в виду. Удалив строку 27, вы получаете другой результат, чем оставляете его, это не должно иметь значения, поскольку функция должна сделать свою собственную копию среза при передаче в качестве аргумента.
Может ли кто-нибудь объяснить это явление?

Ответ 1

Да, все в Go передается по значению. Ломтики тоже. Но значение среза представляет собой заголовок, описывающий смежный раздел массива поддержки, а значение среза содержит указатель на массив, в котором элементы фактически хранятся. Значение среза не включает его элементы (в отличие от массивов).

Итак, когда вы передаете фрагмент функции, из этого заголовка будет сделана копия, включая указатель, который будет указывать на один и тот же массив поддержки. Изменение элементов среза подразумевает модификацию элементов массива подложки, и поэтому все срезы, которые имеют один и тот же базовый массив, будут "наблюдать" изменение.

Чтобы узнать, что в заголовке среза, выберите reflect.SliceHeader тип:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

См. соответствующий/возможный дублирующий вопрос: Параметр функции Golang передан как copy-on-write?

Читайте сообщение в блоге: Go Slices: использование и внутренние параметры