Introduction
In this tutorial, we’ll learn the slice data type and it’s a declaration. Slice is a data type and it is a useful data type. the slices use instead of arrays because they are flexible, you can change their size, you can increase them in size.
The slice is a window on an underlying array. So, every slice, there’s going to be some depends array that is the basis for the slice. The slice is a window of it, a piece of it.
That’s simply what a slice is, a window on a larger array. It is not to be larger, the array can be the same size as the slice. Then, the slice defines at the whole array, but the array can be much bigger than the slice and the slice can be a smaller window on it.
How Does Slice work?
The slices have variable sizes, up to the size of the array. you can increase the size of the slice. An array is a fixed size thing. So, here we have an array of size 100 and we have a slice of size 10, which on that array and it’s the first 10. we can increase the size of the slice to 20, and look at the next 10 elements in the array. and then we can increase to 30 and include the next 10 elements in the array. So, the slices can increase the size of the slice, where you can’t do that to an array.
Now, every slice has basically three properties. One is the pointer that indicates the start of the slice. So every slice has to point to some element of the array that is the first element that includes in the slice.
The next property of a slice is a length, it’s the number of elements in the slice. Because they all have a length.
The limit is the maximum number of elements in the slice. Now, that’s defined by looking at the pointer which is the beginning of slice and looking at the difference between that and the size and the distance to the end of the whole array. Because the size can increase up to the size of the whole, up to the end of the array.
So, the array instance, we have an array of size 100, we got a slice the size 10. then we can increase that slice’s size, the slice starts right at the beginning of the array, you can increase the slice size all the way to 100. if you want to. So it has a capacity of 100. Actually, if you got an array of size 100 but this slice starts at array index 10, then it can only increase to size 90. because by then you reach the end of the array. So the capacity of that slice is small.
Example
Let’s see the following Slice examples.
So, first, we start with the underlying array with literal.
arr := [...]string{"a", "b", "c", "d", "e", "f", "g"}
Now, here we declare two slices on this, with that array as the underlying array, s1, and s2.
s1 := arr[1:3]
s2 := arr[2:5]
The one index is the pointer to the first element of the array, that is inside the slice, and the three indexes is after the end of the slice. So, you can see the slice, s1, it includes the array elements one and two, not three. So, the second number after the colon is after the end.
following arr elements S1 => b & c S2 => c & d & e
a | b | c | d | e | f | g |
0 | 1 | 2 | 3 | 4 | 5 | 6 |
Now, if we see s2 and S2, so S2 starts at two. It includes three and four, does not include five. and the s1, it includes index one and two because one colon three, so three is just past one past the N, and s2 includes two, three and four, and notice that these two slices overlap.
Slices can overlap and it refers to the same elements inside the array.
Length and Capacity
The length and capacity have two functions len and cap, which return the length and capacity of a slice. So, we have our array a1 here, and it’s three elements. Then, we define a slice.
a1 := [3]string("a","b","c")
sli1 := a1[0:1]
fmt.Printf(len(sli1), cap(sli1))
It means that slice includes array index zero but not array index one. the length is actually should be one. It has only one element in it, array index zero. So, now the next statement, we do the print the same. We print length and capacity. The length is one. zero value is the only thing that’s actually in the slice, but its capacity is still three because its size could increase up to three. if it increases the size of the slice to go all the way to the end of the array since the array has three elements in it.
We are initializing the slice at the beginning at array index zero. we can go all the way through array index zero, one, and two and the length of the slice could be up to three. So its capacity is three.
Accessing slices
Actually, if we accessing the slices or referring to slices. then you write to a slice, to an element in a slice, you are writing to the underlying array. the overlapping slices can refer to the same array elements. if you change one slice and change the underlying array, and you can change any of the slice that also accesses that, it also includes that array element.
So, here we have the following array example.
S1 => b & c S2 => c & d & e
a | b | c | d | e | f | g |
0 | 1 | 2 | 3 | 4 | 5 | 6 |
fmt.Printf(s1[1])
fmt.Printf(s1[0])
We have s1 and s2 are two different slices defined on it. See, in that array element two, with the letter of the string “c”. one is actually including s1 and s2. It refers to that second element of the array because s1 zero would refer to the first element of the array. because that’s where s1 starts.
Actually, They’re both referring to the same elements in the underlying array. you can also have slice literals. They use to initialize the slice, just like an array literal can use to initialize an array. when we initialize a slice, that means you’re creating an array. You have to create the underlying array and the slice just covers the entire array.
If we use a slice literal to define a slice, it actually creates an underlying array and it creates a slice to reference the entire array. so, the length and capacity of the slice are the same. So, if we use a slice literal to create this array, its pointer will point to the beginning to array and its length will be the length of the array length and its capacity will also be the length of the array.