First slice

The basic use

Arrays are usually not used in the GO language, but slices are mostly used. See an example of a slice

arr := [...] Int,1,2,3,4,5,6,7,8 {0}s := arr[2:6]
Copy the code

The result of s is [2,3,4,5] (arr from 3 to 5 is left closed and right open).

There are many other uses for slicing, such as:

arr := [...] Int,1,2,3,4,5,6,7,8 {0}fmt.Println("arr[2:6] = ", arr[2:6])
fmt.Println("arr[:6] = ", arr[:6])
fmt.Println("arr[2:] = ", arr[2:6])
fmt.Println("arr[:] = ", arr[:])
Copy the code

Output results:

arr[2:6] =  [2 3 4 5]
arr[:6] =  [0 1 2 3 4 5]
arr[2:] =  [2 3 4 5]
arr[:] =  [0 1 2 3 4 5 6 7 8]
Copy the code

Data structures such as square brackets ([]) with a colon (:) are considered slices. Of course, there are many other ways to declare

A slice is a view of an array

We know that in GO, an array is a value type, and a slice is a reference type, and a slice is a view of an array

func updateSlice(s []int) {
 s[0] = 520
}

func main() {
arr := [...] Int,1,2,3,4,5,6,7,8 {0} s1 := arr[2:]  fmt.Println("Before S1 update")  fmt.Println("s1 = ", s1)  fmt.Println("arr = ", arr)   fmt.Println("Update section S1")  updateSlice(s1)   fmt.Println("After update, the values of s1 and arr")  fmt.Println(s1)  fmt.Println(arr) } Copy the code

Output results:

Before S1 updates1 =  [2 3 4 5 6 7 8]
arr =  [0 1 2 3 4 5 6 7 8]
Update section S1The values of s1 and arr after the update[520 3 4 5 6 7 8] [0 1 520 3 4 5 6 7 8] Copy the code

Since s1 (slice) is a view of ARR (array), when s1 is changed, the value in the array is changed (the element in S1 with index 0 is changed, and the element in arR with index 2 is changed).

Perform sectioning operations on slices

func learnSlice1() {
arr := [...] Int,1,2,3,4,5,6,7,8 {0} s1 := arr[2:6]
 s2 := s1[1:]
 fmt.Println("s1 = ", s1)
 fmt.Println("s2 = ", s2) } Copy the code

Output results:

s1 =  [2 3 4 5]
s2 =  [3 4 5]
Copy the code

S2 is another slice of section S1

Depth understanding slice

Look directly at an example

func learnSlice2() {
arr := [...] Int,1,2,3,4,5,6,7,8 {0} s1 := arr[2:6]
 s2 := s1[3:5]

 fmt.Println("s1 = ", s1)  fmt.Println("s2 = ", s2) } Copy the code

The print of S1, we know for sure, but what is the print of S2 here?

We know that s1 = [2,3,4,5], and s2 is the data in the interval from 3 to 5 of s1, namely s1[3] and s1[4]. But you can see that the largest subscript of S1 is S [3], so does s1[3:5] report an error?

And the answer is no, you can look at the print and explain why

s1 =  [2 3 4 5]
S2 = [5 6] //s1[3], s1[4]Copy the code

You can see that the 6 in S2 is not in S1, and if we try to print s1[4] directly we get an error. But if you print the s2 slice, it will print out the result normally, so how did you get the 6 out?

It says slice is a view of an array. What does the bottom layer look like? How does it view?

S1 := arr[2:6] s1 := arr[2:6] s1 := arr[2:6] s1 := arr[2:6] It doesn’t end at 3, it has 4 and 5, but you can’t get it directly from S1 [4] or S1 [5], but S1 knows that it has 4 and 5 in it, because s1 knows the underlying array

Then, s2 := s1[3:5], which takes the values of the subscripts 3 and 4 in S1. The subscript of S2 is 0, 1, 2 (2 is invisible). The values s1[3] and S1 [4] are 5 and 6 from the perspective of the underlying array

Internal implementation of slice

The slice first has a PTR pointer that points to the element at the beginning of the slice. There’s an len, which is the length of the slice, and when we use the subscript, we can only use the subscript len minus 1, and if it’s greater than or equal to len, we get an error. And then it has a value, cap, which is the length of the array from where the PTR points to

Slice it can scale back, but it can’t scale back. For example, s1:=arr[2:6] s1:=arr[2:6] s1:=arr[2:6

Slice index must not exceed len(s), and backward extension must not exceed the underlying array cap(s)

Look at a wave of examples

func learnSlice2() {
arr := [...] Int,1,2,3,4,5,6,7,8 {0} s1 := arr[2:6]
 s2 := s1[3:5]

 fmt.Printf("s1 = %v, len(s1) = %d, cap(s1) = %d", s1, len(s1), cap(s1))  fmt.Println()  fmt.Printf("s2 = %v, len(s2) = %d, cap(s2) = %d", s2, len(s2), cap(s2)) } Copy the code

The output

s1 = [2 3 4 5], len(s1) = 4, cap(s1) = 7
s2 = [5 6], len(s2) = 2, cap(s2) = 4
Copy the code