While trying to explain a behavior of slicing an array, and the associated resulting capacity, we realized the spec wasn't immediately clear as to whether slicing an array reuses that array. Making it hard to know if it's part of the spec, or an implementation defined detail.
While reading this section, I understood it to say that this array would be used in the slice but not everyone interpreted it that way:
A slice, once initialized, is always associated with an underlying array that holds its elements. A slice therefore shares storage with its array and with other slices of the same array; by contrast, distinct arrays always represent distinct storage.
Would you be able to clarify if the spec guarantees this behavior, or if it's implementation-specific? If the former, would it make sense to add an explicit note to the spec to clear up any confusion? If it's not guaranteed, is it worth calling that out as being implementation specific?
For the record, a slice of an array shares storage with the array. I agree that I don't see an explicit statement of this at https://golang.org/ref/spec#Slice_expressions .
In the slice types section, it says:
A slice, once initialized, is always associated with an underlying array that holds its elements. A slice therefore shares storage with its array and with other slices of the same array
@randall77 that section is about a slice initialisation, not about slice expressions.
@ianlancetaylor I'm sorry, I should have called out that we observed that behavior. :+1: The debate came down to whether that was an implementation-specific behavior, or whether it was a spec-defined behavior. Thank you for the ACK and assignment.
@zerkms a slice expression initializes and returns new slice over an existing backing array referenced by the operand slice https://play.golang.org/p/yfkn4tYP27w
This may actually be covered in the section regarding slice expressions, although maybe the phrasing could use some tweaking to read better for non-English readers:
If the sliced operand of a valid slice expression is a nil slice, the result is a nil slice. Otherwise, if the result is a slice, it shares its underlying array with the operand.
There's a little ambiguity when the operand is an array it doesn't have an _underlying_ array, but is the array itself.
If the sliced operand of a valid slice expression is a nil slice, the result is a nil slice. Otherwise, if the result is a slice, it shares its underlying array with the operand.
@theckman The slice is the _result_, and it is what has an underlying array, _always_, and it is shared with the operand. The spec does not say that the operand has an underlying array too.
@as Yes, thank you for restating what I said in my comment above.
@theckman right back at ya!
Change https://golang.org/cl/177139 mentions this issue: spec: clarify that slice a expression shares underlying array with operand
Most helpful comment
For the record, a slice of an array shares storage with the array. I agree that I don't see an explicit statement of this at https://golang.org/ref/spec#Slice_expressions .