Slice in Go

Slice the concept

Slice is a kind of data structure, is a kind of dynamic array, automatically changes the size as needed, can conveniently manage and use the data set

Internal implementation

  1. Slice based on array implementation, the bottom layer of slice is array.
  2. The slice itself is very small and is an abstraction of an array
  3. Because slicing is implemented based on arrays, the underlying memory is allocated continuously, which is very efficient
  4. Slicing can be indexed, iterated, and garbage collection optimized
  5. Slice is a mapping of array View, common underlying array, change slice will change the underlying array

Slice declaration and initialization

The statement

  • The make method, a single argument, specifies both length and capacity

  • Slice := make([]int, 5)Copy the code
  • The make method, with two arguments, specifies the length and capacity

  • Slice := make([]int, 5, 10) make([]int, 5, 10)Copy the code
    1. The bottom layer of slicing is an array. The default value of slicing is zero
    2. The slice length is 5 and the capacity is 10, so only 5 values can be accessed
    3. The remaining five elements need to be sliced and expanded before they can be accessed
    4. The size of the slice must be greater than or equal to the length of the slice
  • Create slices using :=

    Slice :=[]int{1,2,3,4,5}Copy the code
  • Create a partial slice using :=

    Slice :=[]int{4:1}Copy the code
  • The difference between arrays and slices

    // array array:=[5]int{4:1} // slice:=[]int{4:1}Copy the code
  • The difference between a nil slice and an empty slice, they both have a length and a capacity of 0, pointing to a different underlying array

    • Nil slice The pointer to the underlying array is nil, indicating a nonexistent slice
    • The underlying array that the empty slice points to is the pointer address, which represents the empty slice collection
    Var nilSlice []int // null slice:=[]int{}Copy the code

Create slices based on an existing array or slice

  1. Create a new slice using [I :j], where I is the start of the index and j is the end of the index
  2. Both I and j can be omitted, and default to 0 and len(slice) -1
  3. For an array or slice (capacity k), the length and capacity of a new slice (slice[I :j]) areThe length is j minus IThe capacity ofk - i
  4. The length of the system built-in method islen(slice)The capacity ofcap(slice)

Use the third value to limit slice capacity

  1. Creates a value of length2 minus 1 is 1The capacity of3 minus 1 is 2
  2. The third value cannot exceed the maximum of the original slice capacity
slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:2:3]
Copy the code

Append values to slices

  1. throughappendMethod appends values to slices
slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:3]

newSlice=append(newSlice,10)
fmt.Println(newSlice)
fmt.Println(slice)
//Output
[2 3 10]
[1 2 3 10 5]
Copy the code
  1. throughappendAppend many values at once
NewSlice = append (newSlice, 10, 30)Copy the code
  1. through.andappendAppend slices to slices
slice := []int{1, 2, 3, 4, 5}
newSlice := slice[1:2:3]

newSlice = append(newSlice, slice...)
Copy the code
  1. The append function intelligently increases the size of the underlying array. The current algorithm is that the append function increases the size of the underlying array exponentially when the size is less than 1000. Once the size exceeds 1000, the append function increases the size by 1.25, which means that the append function increases the size by 25% each time.

Iterative slice

  1. usefor rangeIterative slice
slice := []int{1, 2, 3, 4, 5}
for i,v:=range slice{
	fmt.Printf("Index :%d, value :%d\n",i,v)
}
Copy the code
  1. You can also useforIterative slice
slice := []int{1, 2, 3, 4, 5}
for i := 0; i < len(slice); i++ {
	fmt.Printf("Value: % d \ n", slice[i])
}
Copy the code

Pay attention to the point

  1. rangeReturns a copy of the sliced element, not a reference to the element

Pass slices in the function

func main() {
	slice := []int{1, 2, 3, 4, 5}
	fmt.Printf("%p\n", &slice)
	modify(slice)
	fmt.Println(slice)
}
func modify(slice []int) {
	fmt.Printf("%p\n", &slice)
	slice[1] = 10
}
Copy the code

Pay attention to the point

  1. When you pass a copied slice, the underlying array will not be copied and will not be affected. The copy is just the copied slice itself, not the underlying array