Объясните, как работает встроенная функция `copy` в Go. Каковы её основные особенности и в каких случаях она предпочтительнее ручного копирования в цикле?

Ответ

Встроенная функция copy предназначена для копирования элементов из одного слайса (source) в другой (destination). Она возвращает количество скопированных элементов.

Ключевое правило: copy скопирует min(len(src), len(dst)) элементов. То есть, количество скопированных элементов будет равно наименьшей из длин исходного и целевого слайсов.

Пример:

src := []int{1, 2, 3, 4} // Источник
dst := make([]int, 2)   // Целевой слайс с длиной 2

numCopied := copy(dst, src)

fmt.Println(dst)       // Вывод: [1 2]
fmt.Println(numCopied) // Вывод: 2 (скопировано 2 элемента, т.к. len(dst) == 2)

Основные особенности и преимущества перед ручным копированием:

  1. Безопасность: copy корректно обрабатывает случаи, когда исходный и целевой слайсы пересекаются (указывают на одну и ту же базовую область памяти). Ручное копирование в цикле в такой ситуации может привести к неожиданным результатам.
  2. Производительность: Как встроенная функция, copy реализована на низком уровне и оптимизирована. Она, как правило, работает значительно быстрее, чем копирование элементов в цикле for на Go.
  3. Лаконичность: Использование copy делает код более чистым и читаемым.

Важно помнить: Для copy необходимо, чтобы у целевого слайса dst была достаточная длина (не емкость!), чтобы принять элементы. Если вы передадите nil или слайс с нулевой длиной в качестве dst, ничего скопировано не будет.