Sunday, 28 August 2016

go - Why can't I duplicate a slice with `copy()`?



I need to make a copy of a slice in Go and reading the docs there is a copy function at my disposal.





The copy built-in function copies elements from a source slice into a
destination slice. (As a special case, it also will copy bytes from a
string to a slice of bytes.) The source and destination may overlap.
Copy returns the number of elements copied, which will be the minimum
of len(src) and len(dst).




But when I do:




arr := []int{1, 2, 3}
tmp := []int{}
copy(tmp, arr)
fmt.Println(tmp)
fmt.Println(arr)


My tmp is empty as it was before (I even tried to use arr, tmp):




[]
[1 2 3]


You can check it on go playground. So why can not I copy a slice?


Answer



The builtin copy(dst, src) copies min(len(dst), len(src)) elements.



So if your dst is empty (len(dst) == 0), nothing will be copied.




Try tmp := make([]int, len(arr)) (Go Playground):



arr := []int{1, 2, 3}
tmp := make([]int, len(arr))
copy(tmp, arr)
fmt.Println(tmp)
fmt.Println(arr)


Output (as expected):




[1 2 3]
[1 2 3]


Unfortunately this is not documented in the builtin package, but it is documented in the Go Language Specification: Appending to and copying slices:




The number of elements copied is the minimum of len(src) and len(dst).





Edit:



Finally the documentation of copy() has been updated and it now contains the fact that the minimum length of source and destination will be copied:




Copy returns the number of elements copied, which will be the minimum of len(src) and len(dst).



No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...