Maybe this slightly modified version will clear it up for you: https://play.golang.org/p/7pnNMqUVlq0
I declared a [6]int array and sliced it to obtain the slice you started with, and then printed everything you printed, the underlying array’s address and the addresses of the first two elements (when present) too. As you can see, the slices change, but they are all views to the same underlying array. When you slice the array like s[:n] or s[0:n], you are keeping the view from the starting point and you can always regrow it back, but when you slice it like s[1:n], then your view starts at the position 1 of the underlying array, and thus effectively leaving the slice with a capacity of 5 in this case. As you can see, now the underlying array’s address of the new slice has moved to the element at position 1 of the original slice. As stated in https://blog.golang.org/go-slices-usage-and-internals:
Earlier we sliced s to a length shorter than its capacity. We can grow s to its capacity by slicing it again
.
A slice cannot be grown beyond its capacity. Attempting to do so will cause a runtime panic, just as when indexing outside the bounds of a slice or array. Similarly, slices cannot be re-sliced below zero to access earlier elements in the array.
So there’s no way you are going back to position 0 of the original array by reslicing the slice that already started from 1, but you can grow them to anywhere within it’s capacity.
This happens again later when you reslice starting from a position other than 0 and further reduce the capacity. Of course, if you had kept an original slice, resliced it in another variable and then kept reslicing the latter, the former would be left untouched and yield your slice of length and capacity 6 pointing to the original array, as you can see in the last print (don’t mind the names, just kept your function).
Hope this clears things up.