复制切片有什么意义?

What is the point of this snippet of code:

t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
for i := range s {
    t[i] = s[i]
}
s = t

It's from this page: http://blog.golang.org/go-slices-usage-and-internals, and is supposed to grow a slice. However, above that code snippet is a diagram which depicts a slice as a struct with a pointer, a length, and a capacity. Why does each individual entry have to be copied over instead of something like:

t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
t = s[:]
s = t

And if the problem is that the capacity of t is changed to be the same as s, why isn't there another way of setting the pointers to be the same. Or does a slice have a pointer to every single element in the array within its bounds?

Edit: I read a little further and got to this snippet of code:

func CopyDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    b = digitRegexp.Find(b)
    c := make([]byte, len(b))
    copy(c, b)
    return c
}

Its purpose is to stop referencing the file after c is returned by using copy. Does this imply that copy copies the underlying array as well as the slice?

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]