One of the fundamental types that you love used frequently in. Go is a slice,
which is a little, like, or an array, but it isn't an array. In
fact, what a slice consists of is a pointer into some
underlying array into some area of memory and a length. A number of elements
that are in that slice that are available and also a
capacity which is the maximum amount of space that could be used so you can add to
the slice and I just want to review briefly this because sometimes the
's causes confusion, it's worth looking at a little bit more carefully. One note, though, when you
pass a slice between functions in go, you're passing a
reference to it. You're not getting a copy and so you would never find
yourself passing a pointer to a slice. It doesn't make sense. Similarly, there are other
types and go which are past like that maps and channels. For example
are passed around as essentially pointers that you don't see.
So you would never find yourself doing star to a map or if you did it would be a very, very unusual.
Raishin. So I've got a simple little program here which just creates slice and then
re slices it and do some manipulation that can help illustrate, what's happening.
So I created a slice here with some numbers in it, instead of six,
six integers and then I re sliced it taking two
elements from it. Now, remember, the slice syntax is
if you're a mathematician, you would think of this as one come to 3. So it's from
one up to but not including the three. So you're going to get two
elements in there.
And so that will give us the first this element
and this element. And what I've done is then I've just modified
something in the underlying slice this this element
here this 11 up, doubled it and then I've added
an appended to the second slice, another number and I'm going to
print out and examine what's happened to the underlying slices.
So let's run it. So the first thing that
comes out 11 and 21.
Is this, so that's these two elements here, which are now in this particular
slice here, this number was then doubled this
one in the underlying one. But when I printed out middle, it's now been doubled there
as well. So just gives you a reminder that you are actually referring to some other
underlying array. This thing didn't make a copy of anything, I
then added something on to Middle. Now, in this
case, you'll notice that middle got 42 added on to the end of it, so there was middle and
it got 42 out.
Don. But this actually affected the underlying slice. When I
print out numbs here, the underlying one you'll notice that 42
has substituted for this here because this append happened on the
underlying slice itself as well as the slides because these are just pointers
into something underneath. Now, One Thing Worth looking at is what the
capacity of the slices of just go in here and say,
What is the capacity of middle? How much stuff can I store in its run? That you can
see it has five elements. And the reason that comes about is when we sliced it,
we sliced it from this thing and we slide from here. So this is, these are the
five elements. So as I append more and more things, I will
eventually hit that capacity. So let's just add some more numbers on here.
And this is going to here and say middle equals up in the middle
43.
And to this. So we've added a bunch of numbers and let's
print it out.
So that's word perfectly nicely. Now, what's happened to the underlying array?
So what happens the underlying array was? We filled it up to the
point at which it could be filled and then after that
we got some extra elements added on to middle. So middle actually had to change. So
now, it's actually been extended. Now, what happens if
the underlying array changes member that number one there I'm going to double it again
and I'm going to print out these two items
just do this and if you have a
In here within middle and numbs is it's worth noticing.
That previously, when I doubled an element in
numbs, it affected middle because they're pointing to the same underlying array.
But as I appended, I ended up in a situation where
this 44 got doubled in the underlying array, but
not in the slice because I append it past its capacity
and I actually had to get copied and moved is that this is now, this is now
become a different
Slice. So, it's worth noticing that if you're trying to rely on, well, this slices
talking to, you know, is a reference to something underneath, there can be situations
in which that is no longer true, and it can be very confusing. So, in
general, what I like to do is think about not, think about the implementation detail,
just know that it's very fast for kind of normal circumstances. And if I
really need this sort of effect that I've got to be very careful about the capacity.
Now there's other sorts of things you can do with slices that
are
Not built into go for example, if you wanted to remove an element from the middle of a slice,
then you really don't have a lot of choice, other than, to create something else. So for example, let's
suppose I've got middle here, which has got these in and I suppose, I want to get rid of
this 43. Well, there's a couple of ways to do is the simplest is to do something
like this. I'm going to take everything up to that element,
and then I'm going to take everything from that element plus 1. So it's just then a question of
figuring out these offsets. So this is 0
Oh one, two, three. So I'm going to go up to 3 and then 3 plus 1
4. And then I was print out that
I'm sorry, this is a
There we go. So now 43 is disappeared from here. But once again this is
essentially a new slice because I've changed as there was a data copy occurred
at that point. So slices are great for simple operations when you're just working
with them. Moving them around, they're very lightweight because it just a pointer and a
couple of counters as you start to add to them. Then you and
can end up having to reallocate, or move memory around. But in general, there are fantastic
part of go