On Tue, Nov 1, 2022 at 10:49 PM Brian, son of Bob <brianwei...@gmail.com> wrote:
> Can anyone explain these gotchas (demo <https://go.dev/play/p/g40KMK-zsNk>)? > I've tried reading articles on this [one > <https://go.dev/blog/slices-intro>, two > <https://codeburst.io/a-comprehensive-guide-to-slices-in-golang-bacebfe46669>] > but they don't go into enough detail. > > > *Slight gotcha #1: arr[:N] only creates a linked slice when N < len(arr) > and arr[N:] only creates a linked slice when N>0.* > E.g. `y` is linked here: > y := x[:len(x) - 1] > and here: > y := x[1:] > > But not here > y := x[:len(x)] > or here: > y := x[0:] > There is no "linked" slice. A slice is simply three values: pointer to an array, length, and capacity. If x is a slice, then y:=x[j:k] means y.array = &x.array[j] y.cap=x.cap-j y.len=k-j So x[0:] is simply equal to x, and x[1:] is a slice that doesn't have the first element of x. > > Also AFAICT, it's impossible create a link to an empty/nil slice unless > you use pointers. And I'm not sure if it's possible to create a linked > slice that looks at all of the elements in the original without using a > pointer. > > I kind of understand where the Go designers were coming from since it is > probably more efficient to avoid copying all the time. Though by that > logic, I'd still think x[0:] would create a linked slice. > This is not about efficiency. An array is a fixed-length data structure, and if you pass arrays around, you'll get copies of it. A slice is a view of an array. > > > *Gotcha #2: Appending to a linked slice affects the original slice but not > the other way around* > E.g. if `y` is linked to `x` via `y := x[1:], then: > - appending to `y` *might* affect x (see Gotcha #3!) > - appending to `x` won't affect `y` > If there is a link, why does it not work both ways? > Appending to a slice will append the element to the underlying array if the slice has capacity. Otherwise, it will allocate a larger array, copy the old one into the new array, and append to the new array. Because of this, if you do: x:=append(y,elem) If y has enough capacity, then both x and y will point to the same array that will contain elem. If not, a new array will be allocated, elem will be appended to it, and x will point to that new array while y will continue to point to the old array. > > > *Gotcha #3: Using variadic args to append to a linked slice doesn't affect > the other one* > If `y` is linked to `x` via `y := x[:len(x) - 1], then > - append(y, 1) affects x > - append(y, 1, 2) doesn't affect x > I really don't get this one. > This is same as the above case. > > > > Thanks for any insights! > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/7e2b82cc-f5f4-4fe4-ba73-0ff4dead66f7n%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/7e2b82cc-f5f4-4fe4-ba73-0ff4dead66f7n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr8oJUnO7chga32VK83rP3XQduEfTJnm%3DjwZCno1nFdpw%40mail.gmail.com.