Голанг ломтики проходят по стоимости?

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

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

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

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

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

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

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

 type SliceHeader struct { Data uintptr Len int Cap int } 

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

Читать сообщение в блоге: Go Slices: использование и внутренние функции

Давайте будем гением компьютера.