The starting

Arrays and slicing are covered in some detail in the Golang documentation, but this article focuses on arrays and slicing

As it is my personal understanding, there may be some deviation, please correct it

An array of

Golang’s array is simple enough to understand a few concepts

  1. An array is a set of values of the same type with a fixed length and capacity
  2. If the array length is 5, the capacity is fixed at 5
  3. The index of an array starts at 0

Remember, here we define an array of int size 5, which we will slice up later in the slicing tutorial

// This defines an array of length 5, Arr := [5]int{0, 1, 2, 3, Printf(" array p = %p,arr = % v,len = %d,cap = %d\n", &arr, Arr, len(arr), cap(arr)) // 1 FMT.Println(arr[0], arr[1])Copy the code

slice

Basic concepts of slicing

  1. A slice can be thought of as an array of variable length
  2. A slice can be viewed as a reference to a fragment of an array

Create a slice

Let’s start by creating a slice of the ARR array

[1:3] indicates the range from index 1 of array to index 3 of array, which does not include 3. It can be simply understood as index == 1 && index < 3. When the slice is generated, the index also starts from 0 by default.

Printf(" Slice p = %p,arr = %+v, Len = %d,cap = 4 %d\n", &arrSlice, arrSlice, len(arrSlice), cap(arrSlice))Copy the code

Modify the array, slice what happens?

As we mentioned above, slicing is a reference to an array, so what happens when we modify the array’s value?

// Slice p = 0xC00000c060,arr = [10 2],len = 2,cap = 4 FMT.Printf(" slice p = %p,arr = 4 %+v,len = %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), cap(arrSlice)Copy the code

It can be seen that the value corresponding to our slice is also changed to 10. The underlying array existing in the underlying data structure of the slice is the reference passing of the array above. We should still distinguish reference passing and value passing

So correspondingly, if we modify the slice, the array will change accordingly

// For the same reason, Changing slice values also affects the underlying array arrSlice[0] = 8 // slice p = 0xC00000C060, ARr = [8 2], Len = 2, Cap = 4 fmt.Printf(" Slice p = %p,arr = %+v,len =  %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC00001C0F0,arr = [0 8 2 3 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr))Copy the code

What happens when you append slices?

As mentioned above, if we modify slices or arrays, there will be corresponding changes, so what if we append slices?

// Append arrSlice = append(arrSlice, Printf(" sectionp = %p,arr = %+v,len = %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC000090060,arr = [0 8 2 11 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr))Copy the code

We can see that the index = 3 of the array is changed to 11.

  1. The slice index before append is[0, 1]Corresponds to the array[1, 2]
  2. We append one bit here, so the index of the slice is[0]The index of the array is[1, 2, 3]
  3. So if you append a value, it also changes the value of the array

Slice capacity?

From the above code, we can see that our cap is always 4. Why? This involves a capacity calculation formula

  1. When creating slices, we specify that we slice [1,3] of the array, where the cut length is 2
  2. When a slice is created, if the size is not specified, the size will be calculated automatically. If the size is not specified, the slice will be calculated automatically
  3. The formula for calculating the capacity at creation time is: the length at creation time * 2. Our length is 2, and the calculated capacity is 4
  4. In addition, the system determines whether the capacity is sufficient. If the capacity is sufficient, the capacity remains unchanged. If yes, check whether the length is less than 1024. If yes, the capacity is 2; if no, the capacity is 1.25

That’s why our capacity is always 4, right

What happens if the slice size exceeds the array size?

We’ve been saying over and over again that slicing is a reference to an array, so what happens when I slice out of the array?

So let’s do this in code

arrSlice = append(arrSlice, 12, 13, Printf(" slice p = %p,arr = %+v,len = %d,cap = %d\n",  &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC00001C0F0,arr = [0 8 2 11 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr))Copy the code

In the code above, we append three values, 12,13,14.

We can see that the array value has not been modified, as we discussed, on the step, should be an array of the last one will be 12, but not this is a very important concept, when we slice capacity is greater than the underlying array capacity, automatically creates a new underlying array, the cancellation of the original array references

When we slice to unreference the original array, we modify the slice again, and the original array is not affected

ArrSlice [0] = 18 // slice p = 0xC00008c020, ARr = [18 2 11 12 13 14], Len = 6, Cap = 8 fmt.Printf(" slice p = %p,arr = %+v,len = %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC000092060,arr = [0 8 2 11 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr))Copy the code

What happened to the dereferenced array?

According to research, most people say that golang’s garbage collection is automatically collected when the reference is unreferenced and there is nowhere else to reference it. You can try it out

The complete code

The complete code for this article is as follows

// Enda <[email protected]> package main import "FMT" func main() {// Array is fixed length and capacity, and has a set of values of the same type. Arr := [5]int{0, 1, 2, 3, Printf(" array p = %p,arr = % v,len = %d,cap = %d\n", &arr, Arr, len(arr), cap(arr)) // The index of the array starts from 0. Arr [1]) // slice can be regarded as a variable length array // slice can be regarded as a reference to a fragment of array // [1:3] represents the range from array index 1 to array index 3, which does not include 3, Index == 1 && index < 3 // When the slice is generated, Indexes also start at 0 by default, ArrSlice := ARr [1:3] // Slice p = 0xC00000c060, ARr = [1 2], Len = 2, Cap = 4 fmt.Printf(" Slice p = %p,arr = %+v, Len = %d, Cap = %d\n", &arrslice, arrSlice, Len (arrSlice), cap(arrSlice)) So modifying the underlying array changes the value of the slice arr[1] = 10 // slice p = 0xC00000c060,arr = [10 2], Len = 2, Cap = 4 fmt.Printf(" Slice p = %p,arr = %+v,len = %d,cap = %d\n", &arrslice, arrSlice, len(arrSlice), cap(arrSlice)) Changing slice values also affects the underlying array arrSlice[0] = 8 // slice p = 0xC00000C060, ARr = [8 2], Len = 2, Cap = 4 fmt.Printf(" Slice p = %p,arr = %+v,len =  %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC00001C0F0,arr = [0 8 2 3 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr)) // append the slice index to the array [0,1] // The index of the slice is [0,1,2]. The index of the array is [1,2,3]. ArrSlice = append(arrSlice, Printf(" sectionp = %p,arr = %+v,len = %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC000090060,arr = [0 8 2 11 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr)) / // The capacity is calculated by the following formula: If yes, the size will remain unchanged. If no, the size will be less than 1024. If no, the size will be less than 2. The value of the array is not changed. As we said last time, the last bit of the array should be 12, but it is not. This is an important concept. ArrSlice = Append (arrSlice, 12, 13, Printf(" slice p = %p,arr = %+v,len = %d,cap = %d\n",  &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC00001C0F0,arr = [0 8 2 11 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr)) ArrSlice [0] = 18 // slice p = 0xC00008c020,arr = [18 2 11 12 13 14], Len = 6,cap = 8 fmt.Printf(" slice p = %p,arr = %+v,len = %d,cap = %d\n", &arrSlice, arrSlice, len(arrSlice), Cap (arrSlice)) // array p = 0xC000092060,arr = [0 8 2 11 4], Len = 5,cap = 5 fmt.Printf(" array p = %p,arr = %+v, Len = %d,cap = %d\n", &arr, arr, len(arr), cap(arr)) }Copy the code