This is the 28th day of my participation in the August Challenge.

Slice

Slicing is similar to an array and can be thought of as a dynamic array. Slicing is implemented based on arrays, and its bottom layer is an array. Arbitrarily delimit the array, and you get a slice. Now let’s use an example to understand it better, again based on the previous array.

Generate slices based on arrays

Array [2:5] in the following code is the operation to get a slice that contains elements starting at index 2 of array and ending at index 5:

array:=[5]string{"a","b","c","d","e"}

slice:=array[2:5]

fmt.Println(slice)
Copy the code

Note: this is an element that contains index 2 but not index 5, i.e. the number to the right of: is not included.

End slice:=array[start:end]Copy the code

So array[2:5] retrieves c, D, and E, which are then assigned to slice as a slice.

Slicing, like arrays, can locate elements by index. Here, the newly obtained slice slice is taken as an example. The value of slice[0] is C, and the value of slice[1] is D.

In array, the index of element C is actually 2, but after the array is sliced, in the newly generated slice, its index is 0, which is the slice. Although array array is also used at the bottom of the slice, the index range of the slice is changed after the slice.

As can be seen from the following figure, slice is a data structure with three fields, namely, the pointer to array data, length Len and capacity CAP:

There are a few tricks here. Both the start and end indexes in the slicing expression array[start:end] can be omitted. If start is omitted, the default value of start is 0. Here is an example:

  1. Array [:4] is equivalent to array[0:4].
  2. Array [1:] is equivalent to array[1:5].
  3. Array [:] is equivalent to array[0:5].

Slice to modify

The value of the slice can also be changed, which also proves that the underlying slice is an array.

Assigning the corresponding slice index element is a modification. In the following code, change the slice index 1 to f and print the array array:

slice:=array[2:5]

slice[1] ="f"

fmt.Println(array)
Copy the code

You can see the following results:

[a b c f e]
Copy the code

The value of the array has been changed to f, so this also proves that array-based slicing uses the same underlying array, and once the value of the slicing element is changed, the corresponding value of the underlying array will also be changed.

Slice the statement

In addition to getting slices from an array, you can also declare slices, easily using the make function.

The following code declares a slice of type string and length 4. Make can also pass in a size argument:

slice1:=make([]string,4)
Copy the code

In the following example, the newly created slice []string has a capacity of 8:

Slice1: make = (string [], 4, 8)Copy the code

It is important to note that the size of the slice cannot be less than the length of the slice.

The length of the slice, which you already know, is the number of elements in the slice. So what’s the capacity? It’s just the space for slices.

As shown in the above example, Go divides the memory into a content space of 8 capacity (8 capacity), but only 4 memory Spaces have elements (length 4), and the rest of the memory space is free. When append the element to the slice, it will be appended to the free memory. If the length of slices exceeds the capacity, the slices will be expanded.

Slices can be declared and initialized not only by the make function, but also by literals, as shown below:

slice1:=[]string{"a","b","c","d","e"}

fmt.Println(len(slice1),cap(slice1))
Copy the code

Note that the difference between slice and array literals is the length in the brackets []. In addition, slices initialized by literals have the same length and capacity.

Append

We can append elements to a slice using the built-in append function to return the new slice, as shown in the following code:

Slice2 :=append(slice1,"f") slice2:=append(slice1,"f","g") slice2:=append(slice1,slice...) slice2:=append(slice1,slice...)Copy the code

Append function can have the above three operations, you can choose according to your actual needs, Append will automatically handle the problem of insufficient slice capacity need to expand.

Tip: When creating a new slice, it is best to make the length and capacity of the new slice the same, so that the appending operation will generate a new underlying array, which will be separated from the original array, so that the modification of the content will not affect multiple slices due to the sharing of the underlying array.

Slice element cycle

Sliced loops are exactly the same as arrays, but they’re also used for range, so I’m not going to give you an example here, but I’ll leave it as an exercise for you.

In Go language development, slicing is the most used, especially when it is used as a parameter of a function. Slicing is usually preferred over arrays because of its high efficiency and small memory footprint.