Slices are structures that hold a pointer to the array, a length, and a capacity!
So, when you slice a slice, if you perform an array operation like “append” while there is existing capacity, it will use that array space for the new value.
When the sliced value is assigned to another variable, it’s not a pointer that’s copied, it’s a new slice value (with the old length). So, this new value thinks it has capacity to overwrite that last array value - and it does.
So, that also overwrites the other slice’s last value.
If you append again, though, you get a (new) expanded array. It’s easier to see with more variables as demonstrated here: https://go.dev/play/p/AZR5E5ALnLR
(Sorry for formatting issues in that link, on phone)
It's because slices have underlying arrays which define their capacity (cap(s)).
Both slices start out having the same underlying (bigger) array -so appending to one slice can affect the other one.
In the "bonus" part, though, the appends outgrew the original array, so new underlying arrays were allocated (i.e. the slices stopped sharing the same backing array).
Yes-ish? Slices are this weird construct where they sometimes behave like references and sometimes not. When I read the explanation, it always makes sense, but when using them it doesn't. For me the rule is: don't reuse slices and don't modify them unless you are the "owner" of the slice. Appending to a slice that was returned to you from a function is usually a pretty good way to have a fun afternoon debugging.