Representation
Slices are represented by a runtime.slice
struct (slice header):
array
is a pointer to the underlying arraylen
represents the length of a slicecap
indicates the capacity of a slice
Note that, slice is not a pointer to a struct
nil
Slice
nil
slice is actually a zero value of the slice header:
Empty Slice
Empty slice is just a slice with len
and cap
equal to 0 and array
pointing to zero-sized array:
The value of the array
is the address of the runtime.zerobase
, the base address for all 0-byte allocations
Grow Factor
The slices grow as follows:
const threshold = 256
if cap < threshold {
cap = cap*2
} else {
cap = cap + (cap + 3*threshold) / 4
}
So, the growth factor is roughly 2x for small slices and 1.25x for large slices, plus a constant for a smoother transition.
Type Information
Type information about the slice data type is represented by an abi.SliceType
struct:
Invariance and Conversions
Slices are invariant. This is one of the reasons why we can’t convert []T
to an []interface{}
Another, is that memory layout of these two slices is different:
- Each
interface{}
takes up two words. As a consequence, a slice with lengthN
and with type[]interface{}
is backed by a chunk of data that isN*2
words long - This is different than the chunk of data backing a slice with type
[]MyType
and the same length. Its chunk of data will beN*sizeof(MyType)
words long
- Converting a slice to an array yields an array containing the elements of the underlying array of the slice
- Converting a slice to an array pointer yields a pointer to the underlying array of the slice
In both cases, if the length of the slice is less than the length of the array, a panic occurs
Note that converting a nil
slice to an array pointer yields a nil
pointer, while converting an empty slice to an array pointer yields a non-nil
pointer
References
- null - nil slices vs non-nil slices vs empty slices in Go language - Stack Overflow
- Slices from the ground up | Dave Cheney
- Go Slices: usage and internals - The Go Programming Language
- research!rsc: Go Data Structures
- InterfaceSlice · golang/go Wiki · GitHub
- Arrays, slices (and strings): The mechanics of ‘append’ - The Go Programming Language
- Go internals: invariance and memory layout of slices - Eli Bendersky’s website
- Source code: slice.go
- Source code: malloc.go
- Source code: ssa.go
- The Go Programming Language Specification - The Go Programming Language
- slices: amortize allocations in Insert · golang/go@3de5b4d · GitHub
- slices: amortize allocations in Insert · Issue #54948 · golang/go · GitHub