Up to Main Index                              Up to Journal for June, 2014

                    JOURNAL FOR FRIDAY 27TH JUNE, 2014
______________________________________________________________________________

SUBJECT: Re-slicing slices and appending
   DATE: Fri 27 Jun 22:43:49 BST 2014

Since last week WolfMUD development has come to a sudden screeching halt. Not
due to any problems, issues or such-like. I've simply been too busy with a
project @ work *sigh* In fact a week and a half ago I started reading the
release notes for Go 1.3 - still haven't finished reading them...

Before everything came to a stop I had a bug which had me stumped for a while
before going 'doh!' at the obvious mistake - once you spot it!

As we know the append built-in adds elements to the end of a slice returning
the updated slice. The returned slice *may* have a new underlying array if
the current array does not have sufficient capacity. A typical beginner's
mistake is forgetting to store the updated slice. In other words:


  append(s, 1)


This will work okay, but only while there is sufficient capacity in the array
backing the slice. Instead the returned slice should be stored, just in case
the backing array changes:


  s = append(s, 1)


This is just background and not the 'doh!' from above. Bearing in mind the
above consider the following lines of code:


  s1 := []int{1}
  s2 := s1[0:1]
  s2 = append(s2, 2)
  s2[0] = 3


Now what is s1 and s2? s1=[]int{3,2} and s2=[]int{3,2} ? nope... s1 is
[]int{1} and s2 is []int{3,2} - hrm... it's probably easier to see the issue
in this code than the code I was actually debugging but it illustrates the
same issue. So what is going on?

In the first line we create s1 as []int{1} with an anonymous backing array. In
the second line we re-slice s1 to create s2 which is now []int{1} also - both
s1 and s2 have the same backing array.

Now, line three. Here we append 2 onto s2 - oh no! s2 doesn't have enough
capacity! It's okay because we are allocating the updated slice back to s2
again. So we avoided the typical beginners mistake - phew!

But this is where the problem is. Spotted it? s1 and s2 now have different
backing arrays. We can't update s1 and see the changes in s2 or visa versa.

So if you are re-slicing slices and using append take care all of your slices
are using the correct backing array - usually by re-slicing after the append.

Obvious when you think about it ;)

--
Diddymus


  Up to Main Index                              Up to Journal for June, 2014