A slice copy puts selected elements in a separately allocated slice. Use one when retaining a small part of a large slice would keep its backing array alive, or when later writes must not affect the original. section 3.10.1 section 3.9
Give copy a destination with length
Given `src := []int{0, 1, 2}`, `var dst []int; copy(dst, src)` copies nothing: the destination has length zero. Instead, use `dst := make([]int, len(src)); copy(dst, src)`. The result is `[0 1 2]`. `copy` takes the destination first and copies at most the shorter slice's length. `append([]int(nil), src...)` is a one-line alternative, though `copy` is clearer here. section 3.8
func getMessageType(msg []byte) []byte {
msgType := make([]byte, 5)
copy(msgType, msg)
return msgType
}
To retain only a five-byte message type, allocate five bytes and copy into them. Returning `msg[:5]` instead can retain the entire received message's backing array; 1,000 retained prefixes of million-byte messages can therefore hold about 1 GB rather than about 5 KB. section 3.10.1
A full slice expression such as `msg[:5:5]` limits capacity but does not free the original backing array. It can limit where a later `append` writes, but it is not a substitute for a copy when the goal is to release a large source array. section 3.10.1 section 3.9
s := make([]int, 0, 1)
go func() {
sCopy := make([]int, len(s), cap(s))
copy(sCopy, s) #1
s1 := append(sCopy, 1)
fmt.Println(s1)
}()
go func() {
sCopy := make([]int, len(s), cap(s))
copy(sCopy, s) #2
s2 := append(sCopy, 1)
fmt.Println(s2)
}()
With spare capacity, two goroutines appending to slices backed by the same array can write the same location. Here each goroutine allocates and copies before appending, so their writes are isolated. section 9.9
Do not confuse copying elements with the slice copy made when `range` evaluates its expression. In `for range s`, the loop uses a temporary slice whose length stays fixed; that does not establish a separately allocated array of elements. section 4.2
