Dealing with arrays is one of the most trivial however painstaking thing programmers needs to tackle. C/C++ fans have the choice of either fully containerized vectors + advanced data structures, or falling back the primal c pointer arrays. Go sort of absorbs both the c style pointer and the convenient container features modern languages like C++ provide. So in golang array is really dynamic like vectors, and along with array it derives out a “Slice” structure, providing convenient concat/slicing operations, but under the hood it’s no different handling pointers on a pre-allocated array space.
I recently work on projects that makes vast use of append() in Go, and what’s funny about this function is you’ll have to assign back the returned value of this function — which is a pointer to the new/old allocated array, back to the old array pointer, that is the array won’t grow in place. From this perspective Go’s low level nature really exposes — it’s pointer reference may really point to a heap allocation, it’s just shown to the user in a more transparent way. Since we’re really calling append a lot of times, we’d like to see how this allocation actually goes, here’s a sample code snippet on sneak-peeking the allocation of an empty integer array:
import (
“fmt”
)
func main() {
var a []int
for i := 0; i < 50; i++ {
a = append(a, 1)
fmt.Printf(“%p\n”, a)
fmt.Println(cap(a))
fmt.Println(len(a))
}
}
the output is shown as follow, apparently Go is allocating power of 2 exponentially as append() call grows. The cap() output indicate the actually array’s capacity, while len() is the slice length — the actually growth of the array as result of append(). Notice that we actually created a slice by using “[]int” with no size indicator in the bracket. As mentioned before, sometimes you really feel like Go is nothing but a thin decorator on C, except it gives you transparent info on what it’s doing under the hood, like enabling cap() and len() query, rather than in C++ containers where it’s hiding as much information as possible in the so-called object-oriented way.
0x10410020 2 1 0x10410020 2 2 0x10410050 4 3 0x10410050 4 4 0x10454000 8 5 0x10454000 8 6 0x10454000 8 7 0x10454000 8 8 0x10436080 16 9 0x10436080 16 10 0x10436080 16 11 0x10436080 16 12 0x10436080 16 13 0x10436080 16 14 0x10436080 16 15 0x10436080 16 16 0x10456000 32 17 0x10456000 32 18 0x10456000 32 19 0x10456000 32 20 0x10456000 32 21 0x10456000 32 22 0x10456000 32 23 0x10456000 32 24 0x10456000 32 25 0x10456000 32 26 0x10456000 32 27 0x10456000 32 28 0x10456000 32 29 0x10456000 32 30 0x10456000 32 31 0x10456000 32 32 0x10458000 64 33 0x10458000 64 34 0x10458000 64 35 0x10458000 64 36 0x10458000 64 37 0x10458000 64 38 0x10458000 64 39 0x10458000 64 40 0x10458000 64 41 0x10458000 64 42 0x10458000 64 43 0x10458000 64 44 0x10458000 64 45 0x10458000 64 46 0x10458000 64 47 0x10458000 64 48 0x10458000 64 49 0x10458000 64 50