top | item 9555728

(no title)

nicksardo | 10 years ago

The use of `append` is absolutely clear. It always returns a new slice; the compiler forces you to take the value returned.

What scares you is the possibility that the underlying array may be copied to a newer, larger array giving enough space for the appended items. If there exists enough space, why bother with a new allocation? I want `append` to handle this for me. If you want different behavior, you can easily setup your own design with `copy`

Regarding this blog post, if you have multiple slices to the same array and are arbitrarily appending to any of those slices, then your design is wrong to begin with.

This isn't an edge-case but a lack of slice understanding.

discuss

order

karmakaze|10 years ago

You're describing how it actually works which is by way of 'shallow value' semantics which is precisely what the commenter is against. Such semantics requires understanding implementation without a simple opaque description. Either full mutability or 'deep value' semantics is simpler. For instance if the b: = a; followed by a[0] = 2 resulted on a copy on write, then b would be unaffected after the assignment of value. Of course the language and libraries do what they do and the user must be aware. Go was supposed to be easier, so copy-on-write semantics would have made more sense.

a-nom-a-ly|10 years ago

I'm not sure what you're trying to say. This is, IMO, nothing more than a lack of understanding. Is the result of `a := make([]struct{}, 0, 1); b := a; b = append(b, struct{}{}); println(len(a), len(b))` also surprising?

tshadwell|10 years ago

Your understanding is incorrect, too. append() only returns a new slice when "the capacity of s is not large enough to fit the additional values", in which case "append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array."

[-] http://golang.org/ref/spec#Appending_and_copying_slices

skj|10 years ago

No, nicksardo's understanding was quite correct. Slices are values, and it is impossible to return the same one, because value semantics don't work like that.

The slice returned only points to a new array when the capacity is not large enough to fit additional values.

a-nom-a-ly|10 years ago

You seem to be confusing `array` with `slice`. AFAIK, append always returns a new slice. How could it not, when everything is copy/pass by value? A slice is essentially a struct with fields for len, cap and a pointer to an array.