Some tricks for Go slicing

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 1
As 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}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324643935&siteId=291194637