Go slice (comparatively) deeper insights (Episode 3)
In this final episode, we will try to solve the problem mentioned in episode 1 by passing slice by reference.
On line 27, slice mySlice with initial values 1, 2, 3, 4, 5 is created.
From line 28-30, information about mySlice memory address, mySlice.Data memory address and mySlice's len and cap are printed.
On line 32, instead of passing mySlice into myFunc2, we pass memory address of it into myFunc2. myFun2 is invoked.
From line 9-11, we print the same information of *s as that of mySlice. Note that this time, *s and mySlice share exactly the same information: they are stored at the same memory address; *s.Data and mySlice.Data are pointing to the same memory address; Len and Cap are also the same.
On line 13, we change (*s)[0] to 10. Simultaneously mySlice[0] is also changed to 10 because *s and mySlice are the same thing: we pass &mySlice to myFunc2, thus *s is just the same as *&mySlice which is mySlice.
From line 14-17, we again print the same information of *s. As expected, nothing has changed: *s is still in the same memory space, *s.Data is pointing to the same address where mySlice.Data is pointing to, Len and Cap did not change either.
领英推荐
On line 19, we append 6 to *s and give the evaluated result (a new slice at a different memory address with a new Len and Cap, see how it works in Episode 1) to *s. Note that this time, not only *s.Data is pointing to a new memory address, mySlice.Data is pointing to that address as well. This is fundamentally different from episode 2 where only s.Data points to the new address. This is how passing by reference does its job.
From line 20-22, we again print the same information of *s. As we can see, *s is still at the same address as mySlice. Now both mySlice.Data and *s.Data are pointing to the new memory address 0xc0000180f0. Thus, the appending we did to *s did take effect on mySlice because s is just an alias of &mySlice. When we change (*s)[0] to 10 and append 6 to *s, we are actually performing the same operation directly on mySlice instead of a copy of mySlice.
On line 33, mySlice is printed and as explained above, its value is now 10, 2, 3, 4, 5, 6
From line 35-37, same information of mySlice is printed again. Memory address where mySlice is stored stays the same. mySlice.Data is updated to the new memory address. Len and Cap have been updated to 6 and 10.
I drew a diagram explaining the whole process.
To sum up, when we pass a slice by reference (pointer) to a function, the argument of the function behaves just as an alias of the address of the slice. Whatever we do to that dereferenced argument will take effect directly on the original slice because we are not dealing with a copy.
Passing by value or reference depends on various scenarios.