golang slice memory application tips in detail

  • 2020-08-22 22:12:13
  • OfStack

Slices are a very frequent type of aggregation in the Go language, representing variable length sequences, with an underlying reference to an array object. A slice consists of three parts: pointer, length, and volume. The pointer points to the memory address of the underlying array element corresponding to the slice's own first element.

The type of slice is declared as follows:


type slice struct {
 array unsafe.Pointer
 len  int
 cap  int
}

Data from the underlying array can be Shared between multiple slices, and the referenced array intervals may overlap. Using slice this feature we can in the original memory space to slice to heavy, screening, and for the operations, so you don't have to declare one point to the new slice to store the result of memory, so as to save the memory space and extend the underlying array of consumption, in the section length enough when the effect is very significant.

The following examples are all operations on the memory space of the array below the slicing, and it is important to note that these operations also change the array below as they create new slices on the array below.

Deletes the element in the specified location

The following function deletes elements from the original slice at the index position i


func remove(slice []int, i int) []int {
  copy(slice[i:], slice[i+1:])
  return slice[:len(slice)-1]
}

func main() {
  s := []int{5, 6, 7, 8, 9}
  fmt.Println(remove(s, 2)) // "[5 6 8 9]"
}

The built-in copy function makes it easy to copy one slice to another of the same type.

Filter element

The following function screens eligible slice elements from the input source slice and returns a new slice consisting of one eligible element.


type funcType func(T) bool // Represents a filter logic function that can be implemented on demand 

func filter(a []T, f funcType) []T {
  b := a[:0]
  for _, x := range a {
   if f(x) { 
   b = append(b, x)
   }
  }
  return b
}

Inversion section


func reverse(a []T) []T {
  for i := len(a)/2-1; i >= 0; i-- {
    opp := len(a)-1-i
   a[i], a[opp] = a[opp], a[i]
 }
 
 return a
}

Grouping slice

The following function accepts a source slice of type []int and returns a nested slice grouped by a specified length (this is difficult to interpret, but those who have used PHP can interpret it as array_chunk of Go version, see the following example for those who have not). Suppose the denominationof the cut is: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, set the element length batchSize as 3, and the grouped slice returned after the function call is [[0 1 2] [3 4 5] [6 7 8] [9]]


func chunk(actions []int, batchSize int) []int {
 var batches [][]int

 for batchSize < len(actions) {
   actions, batches = actions[batchSize:], append(batches, actions[0:batchSize:batchSize])
 }
 batches = append(batches, actions)
 
  return batches
}

func main() {
 actions := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
 batchSize := 3
  chunks = chunk(actions, batchSize)
  //chunks  for [[0 1 2] [3 4 5] [6 7 8] [9]]
}

By the way, the complete slice expression is as follows:


input[low:high:max]

The effect of the last max is that the cap (capacity) of the resulting slice is ES50en-ES51en.

In-situ de-weighting (for comparable slice types only)


import "sort"

func main() {
 in := []int{3,2,1,4,3,2,1,4,1} // any item can be sorted
 sort.Ints(in)
 j := 0
 for i := 1; i < len(in); i++ {
    if in[j] == in[i] {
      continue
 }
 j++

 in[j] = in[i]
 }
 result := in[:j+1]
 fmt.Println(result) // [1 2 3 4] 
}

Article some examples from golang official GitHub wiki, introduced many slices in this wiki use skills, can learn more visit golang GitHub Wiki https: / / github com golang/go wiki/SliceTricks # filtering - without - allocating


Related articles: