Go programming language is easy to learn, but there are some tricky traps. This article series is trying to show these booby traps so that you avoid them.
Let’s consider this code (code on the Playground):
In this example, we send an array by value to a function that modifies it. As we sent it by value, original value is not modified. Thus when we run it, we have:
Now let’s replace our array with a slice (code on the Playground):
When we run this example:
This might sound strange as we sent the slice by value, original should not have been modified!
Take five minutes to try to figure out why this happens and then have a look at the explanation below.
When we send a slice by value, everything happens as if we had send it by reference. Slices behave as if we passed an array by reference (code on the Playground):
Which behaves as slices:
The explanation is quite simple: slices are structures that contain a reference to an array, as we can see in source code for slices:
Thus, when you pass a slice by value, the structure is copied, and the array is the same, and when you modify the array, the original slice points to the same array, and it is also modified
Let’s say we want to upper case first letter of names in
User, as follows (code on the Playground):
If we run this code, we see that it doesn’t work as expected:
Why is this code not working? How could we fix it?
This code doesn’t work as expected because in each loop, we copy struct
User and thus when we modify it, original value is not updated.
We can fix it as follows (code on the Playground):
We modify the original value and thus it works as expected:
You should be aware that when we loop with
range, we copy values and thus if we modify them, the original one is not.