To unpack what Jan wrote a little: when slicing, you can specify a
third integer which becomes the capacity of the new slice. So
b := a[:len(a):len(a)]
will create a new slice b with len(b) = len(a) and cap(b) = len(a).
Without the third argument, cap(b) = cap(a). When cap(a) > len(a) you
have the situation where append(a, 123) is quick: is can just insert
the element into the underlying array without having to reallocate
anything.
So the line
b := append(a[:len(a):len(a)], 3, 4)
does two things: it slices a to obtain a new slice with a lower than
normal capacity. Because the capacity exactly matches the length of
the new slice, trying to append to it is guaranteed to reallocate the
underlying array. So append makes a new, larger array and copies
len(a) elements into it. It then writes 3 and 4 into the new array as
well before returning a slice of the array. That slice becomes b.
From that point onwards, a and a are no longer connected via the
underlying array.
BTW, I was about to say that you could simplify the line one step further with
b := append(a[::len(a)], 3, 4)
but that gives a compilation error:
prog.go:11: middle index required in 3-index slice
I wonder what the rationale is for this? It seems inconsistent to me
since the second (middle) index has a useful default (len(a)) that is
used when there are only two indexes used.
--
Martin Geisler