todo Read https://go.dev/blog/slices-intro
It’s a dynamically-sized array. Much more commons than arrays.
Similar to Python’s list.
Init
The type []T
is a slice with elements of type T
.
Slice is a reference to an underlying array. Similar to Python. Changing the underlying array changes it for every slice that share the same reference.
Slice literals:
Slice expressions. All produces the same result:
Slices can include other slices:
Length and capacity
Slice has a length and a capacity.
- Length - number of elements the slice contains.
- Capacity - number of elements in the underlying array counting from the first element in the slice (from start of the slice to the end of an array).
Example:
Output is:
len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]
Nil
The zero value of a slice is nil
. A nil slice has a length and capacity of 0 and has no underlying array.
Output is:
[] 0 0
nil!
Init with make
If you know approximately how many items will be in the slice, init it with the cap value specified - it will improve the performance.
Never specify a capacity that’s less than the length! It is a compile-time error to do so with a constant or numeric literal. If you use a variable to specify a capacity that’s smaller than the length, your program will panic at runtime.
Capacity that is < length is a compile-time error in Go. If specified with a variable and < than length, the program will Go panic at runtime.
Append
Use built-in append
function to append new elements to a slice. Slice will grow as needed.
If there are no more room for the new elements, Go will allocate more memory to the underlying array, sometimes with some additional extra space than needed for the current operation.
When a slice grows via append, it takes time for the Go runtime to allocate new memory and copy the existing data from the old memory to the new. The old memory also needs to be garbage collected. For this reason, the Go runtime usually increases a slice by more than one each time it runs out of capacity. The rule as of Go 1.18 is to double the capacity of a slice when the current capacity is less than 256. A bigger slice increases by (current_capacity + 768)/4. This slowly converges at 25% growth (a slice with capacity of 512 will grow by 63%, but a slice with capacity 4,096 will grow by only 30%).
With a spread(q Is it called like that in Go?) operator ...
you can append an entire slice:
Compare
Slices aren’t comparable.
The only thing you can compare a slice with using == is nil
:
To compare slices a slices
package from the standard library has:
The
reflect
package contains a function calledDeepEqual
that can compare almost anything, including slices. It’s a legacy function, primarily intended for testing. Before the inclusion ofslices.Equal
andslices.EqualFunc
,reflect.DeepEqual
was often used to compare slices. Don’t use it in new code, as it is slower and less safe than using the functions in theslices
package. Learning Go
Emptying
As of Go 1.21 a clear()
function can be used to set all slice elements to their zero values.
Copy
Use built-in copy()
. It will copy as much elements from the source as possible up to its length.
It’s also possible to copy slices between the same underlying slice:
Convert to array
Explicit type conversion required:
The size of the array must be specified at compile time. It’s a compile-time error to use [...]
in a slice to array type conversion.