Empty slices are also slices
Unlike maps, unallocated slices are also available:
- The length and capacity of a nil slice are both 0;
- You can append to an empty slice and Go will automatically allocate;
- You can also directly iterate over an empty slice
var s [] int64 // nil, len 0, cap 0 for i := range s { fmt.Println("this will not be printed") } s = append(s, 1) // len 1As a result, if the value of a map is of type slice, there is no need to create a slice for a new key.
m := map[string][]int64{} for { // do something if _, found := m[key]; !found { m[key] = []int64{value} } else { m[key] = append(m[key], value) } }The above code can be replaced with
m := map[string][]int64{} for { // do something m[key] = append(m[key], value) }
Re-slicing a slice will share the same underlying array
A slice is a pointer to an array. Re-slicing (eg s2 := s1[a:b] ) creates a new pointer to the same underlying array with a different starting offset and slice length.
As a result, the append operation modifies all slices.
s1 := []int64{1, 2, 3} s2: = s1 [: 1] s2 = append(s2,0) fmt.Println(s1) // []int64{1, 0, 3}
...unless a new array needs to be allocated:
s1 := []int64{1, 2, 3} s2: = s1 [: 1] s2 = append(s2,0,0,0) // reallocates a new underlying array fmt.Println(s1) // []int64{1, 2, 3}