This is the 9th day of my participation in Gwen Challenge

These reviews

Previous articles focused on the Go based syntax of Go containers: arrays. In this paper, specific sections will be used.

Containers commonly used in Go

Golang provides common container implementations in the form of a standard library, which basically meets our daily development needs. Let’s look at the use of the Go array.

slice

A slice is a reference to a contiguous fragment of an array, which is a variable-capacity sequence. We can simply understand a slice as a dynamic array. Its internal structure includes the pointer to the underlying array, its size and capacity. It references the underlying array through the pointer and restricts the read and write operations to the data within a specified area.

The structure of the slice is composed of three parts:

  • arrayIs a pointer to the underlying array of stored data;
  • lenRefers to the length of the current section, that is, the number of members;
  • capRefers to the current slice capacity, which is always greater than or equal tolen.

We can generate a slice from the original array, then the generated slice pointer points to the original array, the generated style is as follows:

slice := source[begin:end]
Copy the code

Source represents the original array that generates the cut skin, begin represents the beginning position of the slice, end represents the end position of the slice, and does not contain the member pointed to by the end index. The specific effect is shown in the following example:

source := [...]int{1.2.3}
sli := source[0:1]

fmt.Printf("sli value is %v\n", sli)
fmt.Printf("sli len is %v\n".len(sli))
fmt.Printf("sli cap is %v\n".cap(sli))
Copy the code

The output is:

sli value is [1]
sli len is 1
sli cap is 3
Copy the code

Within this slice, we can only access values within the length of the slice, and if the index accessed exceeds the length of the slice, the compiler will throw an exception with an out-of-bounds index. If we modify the member in the slice at this time, since the slice is a reference to the original array, modifying the slice means modifying the original array, as shown in the following example:

sli[0] = 4
fmt.Printf("sli value is %v\n", sli)
fmt.Printf("source value is %v\n", source)
Copy the code

The result is as follows:

sli value is [4]
source value is [4 2 3]
Copy the code

In the example above, we changed the values in the slice, causing the values in the original array to change as well.

We can also create slices dynamically using the make function, specifying the length and capacity of the slice during creation, as shown in the following style:

make([]T, size, cap)
Copy the code

T is the type of member in the slice, size is the length of the current slice, cap is the pre-allocated length of the current slice, that is, the capacity of the slice. Here is an example:

sli = make([]int.2.4)
fmt.Printf("sli value is %v\n", sli)
fmt.Printf("sli len is %v\n".len(sli))
fmt.Printf("sli cap is %v\n".cap(sli))
Copy the code

The output is as follows:

sli value is [0 0]
sli len is 2
sli cap is 4
Copy the code

You can see from the above output that the members in the new slice created by the make function are initialized to the initial values of the type.

summary

This paper mainly introduces the basic use of slice. The essence of slice is a structure, which contains three parts: Address + len + Cap. Therefore, as a reference space, the space and the element space are completely two Spaces, so the first address of slice and the first address of the first element are completely different.

The next article will take a closer look at aspects and compare slicing and arrays.