I’m participating in nuggets Creators Camp # 4, click here to learn more and learn together!

review

The last article covered slice definition initialization, reference type characteristics, and how to slice using arrays.

This article introduces make(), append() and copy() of slices. Carry on the detailed introduction and the application actual combat to the knowledge point.

Deepen the understanding

  1. The essence of slicing: the essence of slicing is a box, box a piece of continuous memory
  2. Slicing is a reference type, where the real data is stored in the underlying array
  3. Slicing can simply be understood as a shortcut, and modifications affect each other
  4. To determine whether a slice is empty, len(s) == 0 is used, but S ==nil is not used

Create section make

Please define an integer slice with length 5 and capacity 10.

The code:

S1: = make (int [], 5, 10) FMT. Printf (" s1: % v len (s1) : % d cap (s1) : % d \ n ", s1, len (s1), cap (s1))Copy the code

Print result:

Analysis: The first argument to make() specifies the array type of the slice, the second parameter specifies the length of the slice, and the third parameter specifies the size of the slice.

Better understand length and volume

Printf("s1: %v len(s1) : %d cap(s1) := make([]int,5,10) %d\n", s1, len(s1), cap(s1)) s2 := make([]int, 0, 10) fmt.Printf("s2=%v len(s2)=%d cap(s2)=%d\n", s2, len(s2), cap(s2))Copy the code

Print result:

Analysis: We can see that the number of elements in defining slices is related to length, because length is the number of elements.

We’ll focus on capacity next when we introduce Append ().

Slice reference type actual combat

In the code

S3 := make([]int, 3, 3) s3 = []int{1, 2, 3} s4 := s3 // S4) / / [1 2 3] [1 2 3] s3 [0] = 1000 FMT. Println (s3, s4) / / [2, 3, 1000] [1 2 3] FMT. Println (" -- -- -- -- -- ") / / array a3: = [3] int {1, 2, 4} a4 := a3 fmt.Println(a3, a4) a3[0] = 1000 fmt.Println(a3, a4)Copy the code

Print result:

Analysis: From the print results above, we can intuitively see the nature of slice reference types, which will affect each other when slice modification; Arrays, as value types, do not affect each other.

Traversal of slices

Just like an array, just iterate through it with fori or for range.

s3 := make([]int, 3, 3)
s3 = []int{1, 2, 3}

for i := 0; i < len(s3); i++ {
   fmt.Println(s3[i])
}

for i, v := range s3 {
   fmt.Println(i, v)
}
Copy the code

append

First, we define a slice

S1: string [] = {" Beijing ", "Shanghai", "dalian", "foshan"} FMT) Printf (" s1 = % v len (s1) = % d cap (s1) = % d \ n ", s1, len (s1), cap (s1))Copy the code

Print result:

Analysis: We found that both the length and the capacity of the slice were 4

We then append an element using the append() function

S1: string [] = {" Beijing ", "Shanghai", "dalian", "foshan"} FMT) Printf (" s1 = % v len (s1) = % d cap (s1) = % d \ n ", s1, len (s1), Cap (s1) s1 = append (s1, "tangshan") / / slice append (), after additional FMT. Printf (" s1 = % v len (s1) = % d cap (s1) = % d \ n ", s1, len (s1), cap (s1))Copy the code

Print result:

Analysis: The length changed from 4 to 5, we can easily understand; Why does the capacity go from 4 to 8?

This is the automatic expansion mechanism of Go language for slices. Append () appends elements. When the original underlying data capacity is insufficient, go will replace the underlying array, which is a set of capacity expansion strategy of GO language

I will write a separate article later on how the automatic expansion strategy is implemented. Welcome to my Go Language learning column

Several additional

The concept of multiple appends is easy to understand, just calling append() multiple times

Here’s an example:

S1: string [] = {" Beijing ", "Shanghai", "dalian", "foshan"} FMT) Printf (" s1 = % v len (s1) = % d cap (s1) = % d \ n ", s1, len (s1), Cap (s1)) s1 = 1 cap(s1)) s1 = 1 cap(s1)) s1 = 1  fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1)) var s2 []string s2 = append(s1, "Male" Ann) FMT. Printf (" s2 = % v len (s2) = % d cap (s2) = % d \ n ", s2, len (s2), cap (s2))Copy the code

Print result:

Analysis: S1 appends elements twice and assigns them to S2

Append multiple elements

When we need to append multiple elements, can we only call Append as many times as above?

Of course not.

Here’s an example:

S1: string [] = {" Beijing ", "Shanghai", "dalian", "foshan"} s3: = [] string {" taiyuan ", "shijiazhuang"} var s4 [] string s4 = append (s1 and s3...). / /... FMT.Printf("s4: %v",s4)Copy the code

Print result:

Note: The second argument to append, we pass in a slice that needs to be written dead after the slice… Is used to cut the slice, and the value of the slice is used as the element appended to the first parameter.

Duplicate slice

Here are two ways to demonstrate:

S1 := []int{1, 2, 3} var s2 = s1 Copy var s3 = make([]int, 3) copy(s3, s1) FMT.Println(s1, s2, s3) [1, 2, 3]Copy the code

Print result: all return [1, 2, 3]

S3 := make([]int, 5) s3 := make([]int, 5)

Did the smart guys ask questions?

Since the result is the same, why is copy introduced?

Let’s go on and see why.

S1 := []int{1, 2, 3} var s2 = s1 Copy var s3 = make([]int, 3) copy(s3, s1) s1[0] = 11 FMT.Printf("s1:%v s2:%v s3:%v",s1, s2, S3) //s1 and S2 are [11 2 3]Copy the code

Print result:

S1 and s2 are [11 2 3] and s3 are [1 2 3].

Remove elements

Note: Deleting an element in a slice cannot be done directly. You can use a combination of split +append to delete an element in a slice

For example, remove element 2 from S3.

s3 := []int{1, 2, 3} s3 = append(s3[:1], s3[2:]...) // The first reason for this is that one of the accepted parties is to append the following element to the first FMT.Println(s3)Copy the code

Print result:

Note: there is a comment I added in the code snippet above: the first slice in the append() function does not need to be broken apart, because one, as an accepted party, appends the following element to the first slice.

Array slice

a1 := [...] S1: int {1, 2, 3} = a1 [:] FMT. Printf (" a1 type: % T \ ns1 type: % T ", a1, s1)Copy the code

Print result:

We practice

Guess what the following program would do:

s1 := make([]int, 5, 10)
for i := 0; i < 10; i++ {
   s1 = append(s1, i)
}
fmt.Println(s1)
Copy the code

First,

Don’t

to

see

a

case

.

.

.

Print result:

Analysis: Let’s calm down and deduce it step by step:

  1. S1 := make([]int, 5, 10) make([]int, 5, 10)
  2. The for loop appends the increment of I to the slice above each time
  3. So the final print is: [0 0 0 0 0 0 1 2 3 4 5 6 7 8 9]

conclusion

This article summarized the use of make to generate slices, append to slice elements, copy to copy slices, create new memory space, and use slice splitting and Append to delete slices.

The last

Thanks for reading and welcome to like, favorites,coin(attention)!!