The copy(dst, src []T) int function copies elements from src to dst.
min(len(dst), len(src)).src[i] are copied to dst[i].Nuances and Limitations:
dst has a shorter length than src, only as much data will be copied as is allowed by the length of dst.dst has a greater capacity than its length, does copy expand the slice? — No, only len(dst) is considered the target. For expansion, use append beforehand.Example:
a := []int{1,2,3,4,5} b := make([]int, 3) copy(b, a) // b: [1 2 3]
Overlapping:
x := []int{1,2,3,4} copy(x[1:], x[:3]) // [1 1 2 3]
Can copy() be used to increase the length of a slice? What will happen if a destination slice of greater capacity but smaller length than needed is passed to copy?
Answer:
dst = dst[:newLen], then use copy()Example, often non-obvious:
a := []int{1,2,3} b := make([]int, 0, 5) copy(b, a) // b will remain empty, since len(b) == 0 b = b[:len(a)] copy(b, a) // now b: [1,2,3]
Story
In the project, data was copied from one slice to another, expecting that copy would automatically expand the length of dst as needed. This did not happen, elements were not copied, resulting in null data coming back in the API response. The error was found only after comparing lengths of slices — the problem was that dst had a large capacity, but its length was 0.
Story
A part of the microservice was working with overlapping slices, mistakenly assuming that copy would always work correctly. As a result, forward copying destroyed the original data, leading to "invisible" bugs when working with buffers. This was resolved by using a temporary buffer (copy(tmp, src), then copy(dst, tmp)).
Story
An engineer optimized the array using copy to sort the data between slices. He expected that copy would adjust the length of dst. It turned out not to be the case, and panics and out-of-bounds access to meaningful data began to appear — they forgot to correctly change the length of the slice before copying.