To construct a new, higher capacity underlying array with the same length and values as the old underlying array. The old underlying array will be reclaimed by the garbage collector. For example,
package main
import "fmt"
func main() {
s := []byte{0, 1, 2, 3, 4}[:3]
fmt.Printf("s: %p %d %v %d %v
", &s[0], len(s), s, cap(s), s[:cap(s)])
t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
fmt.Printf("t: %p %d %v %d %v
", &t[0], len(t), t, cap(t), t[:cap(t)])
for i := range s {
t[i] = s[i]
}
s = t
fmt.Printf("s: %p %d %v %d %v
", &s[0], len(s), s, cap(s), s[:cap(s)])
fmt.Printf("t: %p %d %v %d %v
", &t[0], len(t), t, cap(t), t[:cap(t)])
}
Output:
s: 0x10500168 3 [0 1 2] 5 [0 1 2 3 4]
t: 0x1052e130 3 [0 0 0] 12 [0 0 0 0 0 0 0 0 0 0 0 0]
s: 0x1052e130 3 [0 1 2] 12 [0 1 2 0 0 0 0 0 0 0 0 0]
t: 0x1052e130 3 [0 1 2] 12 [0 1 2 0 0 0 0 0 0 0 0 0]
The Go Programming Language Specification
Appending to and copying slices
The function copy copies slice elements from a source src to a
destination dst and returns the number of elements copied. Both
arguments must have identical element type T and must be assignable to
a slice of type []T. The number of elements copied is the minimum of
len(src) and len(dst).
Examples:
var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6)
var b = make([]byte, 5)
n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello")
If we return a reference to b
, we pin the whole underlying array for b
. Since b
refers to a file, that could easily be megabytes or gigabytes. By returning a new underlying array c
, which is the exact size of the number, a few bytes, there will no longer be a reference to the large underlying array for b
and it will be reclaimed by the garbage collector. The copy
built-in function copies values from b
to c
. For example,
package main
import "fmt"
func Copy() []byte {
b := []byte{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Printf("b: %p %d %v %d %v
", &b[0], len(b), b, cap(b), b[:cap(b)])
b = b[:2]
fmt.Printf("b: %p %d %v %d %v
", &b[0], len(b), b, cap(b), b[:cap(b)])
c := make([]byte, len(b))
copy(c, b)
fmt.Printf("c: %p %d %v %d %v
", &c[0], len(c), c, cap(c), c[:cap(c)])
return c
}
func main() {
d := Copy()
fmt.Printf("d: %p %d %v %d %v
", &d[0], len(d), d, cap(d), d[:cap(d)])
}
Output:
b: 0x10500168 8 [0 1 2 3 4 5 6 7] 8 [0 1 2 3 4 5 6 7]
b: 0x10500168 2 [0 1] 8 [0 1 2 3 4 5 6 7]
c: 0x10500178 2 [0 1] 2 [0 1]
d: 0x10500178 2 [0 1] 2 [0 1]