Grab a Slice on the Go

The answer is in the next section.

Memory allocation of slicesThis is the most important aspect of slices.

If you do not know how the size of slices can be dynamically changed, your code might not behave as you expected.

Here’s an example:Most people would expect this output:a: [1 2] b: [1 2 3] c: [1 2 4]a: [1 2 3] x: [1 2 3 4] y: [1 2 3 5]But the actual output looks like this:a: [1 2] b: [1 2 3] c: [1 2 4]a: [1 2 3] x: [1 2 3 5] y: [1 2 3 5]The second one is correct.

Let me explain.

When the slice length is equal to its capacity and you try to append a new element to it, then the new memory is allocated to the slice which has double capacity as compared to the earlier capacity (most of the time).

So in case 1 at line 10, a has capacity and length both equal to 1,In line 11, a gets allocated to a new address with capacity 2 (double the earlier one) and its length is also 2 (as two elements are present).

In line 12, a has capacity = length, hence line append(a, 3) creates a new array with capacity 4 (double the capacity of the earlier one) and returns the slice reference to b.

Now b is a slice which has length = 3 and capacity =4.

Here, the important point is that b is not referencing the underlying array of a , it is referencing a new array which has length = 4.

a still has capacity and length =2.

In line 13, the same thing is happening as line 12, since a still has the length and capacity = 2, line append(a, 4) will create a new array with length 4 (double the capacity of a as a’s len(a) = cap(a)) and return the slice reference to c .

Now c is also a slice with len = 3 and capacity =4.

And same as line 12, c is not referencing to the underlying array of a , it is referencing to a new array which has length = 4.

a still has capacity and length = 2.

Case 1Before line 17, a’s length and capacity are both 2.

But in line 17, a’s capacity has been changed as line a = append(a, 3) creates a new slice with capacity 4 (double a’s last capacity) and returns a slice reference to a itself.

So after line 17, a has length = 3 (elements are 1, 2 and 3) and capacity =4.

Hence in line 18, x := append(a, 4) will append 4 to a (as a has capacity = 4 and currently has only 3 elements) and return the reference to x.

In line 19, same as line 18.

y := append(a, 5) will append 5 to a (as ahas capacity = 4 and currently has 3 elements) and return the reference to y.

Case 2 (This is the scene after line 19)The interesting fact is that in case 2, a, xand yare referencing the same array.

Hence, changes done by y:= append(a, 5) are being reflected in xalso.

This is why the output is printing the same elements for x and y .

So, whenever you are working with slices and using append, beware of these scenarios.

Also, one more important difference between array and slice is that you can compare two arrays but you cannot compare two slices in Golang.

Why?.????.This is an exercise for the reader.




org/go-slices-usage-and-internalsClearly, we are blessed to have smart engineers at GOJEK, and we’re also scaling fast ????.

Our 18+ products are supported by 500+ microservices, so there’s no lack of fun problems to solve.

If that sounds like your kind of work environment, check out gojek.

jobs, and help us shake things up in Southeast Asia ????gojek.


. More details

Leave a Reply