This is a creation in Article, where the information may have evolved or changed.
Huangwenwei-Between the lines | Arrays and slices in golang (slice)
Chinese description Conventions
Array: Arrays
Slice: Slicing
To do a test, do not run the following code on the machine, please give the output
vals :make([]int, 5)for i:= 0; i < 5; i++ { vals = append(vals, i)}fmt.Println(vals)
If you guess the result is [0 0 0 0 0 1 2 3 4]
, congratulations on your correct answer.
Why not the right answer [0 1 2 3 4]
?
Most of them are like me. Golang beginners will get the wrong test, in this article, let's explore why not the output we expect and the usage of capacity and length in the slice data type.
Slices VS Arrays
The initial UI may distinguish between arrays and slices in Golang, but if you are accustomed to using slices, you will greatly optimize your code;
There are many differences between arrays and slices, but here we remember that the biggest difference between them is that the fixed array size is part of the array declaration, and the slice can have a dynamic size. So how does it manifest in the actual coding? For example val a [10]int
, this array has a fixed size of 10, but cannot change its length; if we call len(a)
, return 10, because length is part of the array; This leads to the problem that if there is an array length of more than 10 requirements, you must create another array object, for example val b [11]int
, and copy the value of array A to array B.
Fixed-length arrays are very useful in some scenarios, but usually our flexible arrays require a "No fixed size array", the most straightforward way to declare an array is to give a large enough length, for example:
var vals [20]intfor i := 0; i < 5; i++ { vals[i] = i * i}subsetLen := 5fmt.Println("The subset of our array has a length of:" subsetLen)// Add a new item to our arrayvals[subsetLen] = 123subsetLen++fmt.Print("The subset of our array has a length of:", subsetLen)
In the above example, when we declare an array with a length of 20 and a variable we "set" its length to 5, after we add an element to it, the subset increases by 1, and the length of the array becomes 6
Roughly speaking, this is the principle of slicing, by setting a value to limit the maximum length of the array, in the above example is 20, and the slice also has a value to represent the true length of the array elements, in the above example is subsetlen; so the slices have capacity caps and Length len two concepts. The internal implementation of the slice is based on an array, but is more flexible and more efficient to use. The cap limits the increase in the number of elements in the slice, and through the append
function, we do not need to care about the upper limit of the array.
Back to our test questions.
After understanding the concepts and differences between arrays and slices, let's explain the quiz again.
make
The function can declare a slice, the first parameter represents the type, the second parameter represents the length of the type, the third parameter is an optional parameter, and the upper limit of the type is represented;
make([]int, 5)
It means we're going to create a new slice with a length of 5, and the tile's default hold cap (capacity) is the same as the length. But the function indicates that the slice append
adds an element, and the upper limit of the slice increases at the same time, adding an element to the end of the slice. That is, the default slice value to [0 0 0 0 0]
add an element will be placed after the fifth element, so the result is as follows:
vals := make([]int, 5) fmt.Println("Capacity was:", cap(vals)) for i := 0; i < 5; i++ { vals = append(vals, i) fmt.Println("Capacity is now:", cap(vals))}fmt.Println(vals)// output: [0 0 0 0 0 0 1 2 3 4]
If you modify to the following code, the output is[0, 1, 2, 3, 4]
vals := make([]int, 5) for i := 0; i < 5; i++ { vals[i] = i}fmt.Println(vals)
The code is not concise enough to retrofit: we set the length of the Vals to 0 and hold the upper limit to 5.
vals := make([]int, 0, 5)for i := 0; i < 5; i++ { vals.appen(i)}fmt.Println(vals)
Finally, if you know the upper limit of the slice, it is advisable to add a third parameter to the Make function.