Функция copy(dst, src []T) int копирует элементы из src в dst.
min(len(dst), len(src)).src[i] копируются в dst[i].Тонкости и ограничения:
dst имеет меньшую длину, чем src, скопируется только столько данных, сколько позволяет длина dst.dst ёмкость больше длины, расширяет ли copy срез? — Нет, только len(dst) считается целевым. Для расширения — предварительно используйте append.Пример:
a := []int{1,2,3,4,5} b := make([]int, 3) copy(b, a) // b: [1 2 3]
Перекрытие:
x := []int{1,2,3,4} copy(x[1:], x[:3]) // [1 1 2 3]
Может ли copy() использоваться для увеличения длины среза? Что произойдет, если передать в copy срез-назначение большей емкости, но меньшей длины, чем необходимо?
Ответ:
dst = dst[:newLen], затем используйте copy()Пример, часто неочевидный:
a := []int{1,2,3} b := make([]int, 0, 5) copy(b, a) // b останется пустым, т.к. len(b)==0 b = b[:len(a)] copy(b, a) // теперь b: [1,2,3]
История
В проекте копировали данные из одного среза в другой, рассчитывая, что copy автоматически расширит длину dst до необходимой. Это не произошло, элементы не скопировались, в результате в ответе API приходили нулевые данные. Ошибку нашли только после сравнения длины срезов — проблема оказалась в том, что у dst была большая ёмкость, но длина равна 0.
История
Часть микросервиса работала с перекрывающимися срезами, ошибочно рассчитывая, что copy всегда сработает корректно. В результате копирование вперёд разрушало оригинальные данные, возникали "невидимые" баги при работе с буферами. Решилось использованием временного буфера (copy(tmp, src), потом copy(dst, tmp)).
История
Инженер оптимизировал массив, используя copy для упорядочивания данных между срезами. Ожидал, что copy скорректирует длину dst. Оказалось, что это не происходит, и стали появляться паника и выход за рамки значимых данных — забыли корректно изменить длину среза перед копированием.