Welcome back.
Lastly you have learned how to create your own functions.
Now it's time to talk about pointers.
At the end of this section you're going to rewrite the log parser project using pointers.
You're also going to learn about the pointer semantics.
You will understand the implications of passing pointers to struct, map and slice values to functions.
So at the end of the section you will understand everything about pointers.
All right let's get started.
A pointer stores the memory address of a value located in computer memory such as a variable so you
can use it to retrieve and update a value through its memory address before going on.
Here is a little warning.
In this lecture I'm going to use a few variables such as these ones P is short for a pointer variable
V is short for a variable.
So please don't be confused about why I am using these names.
I could have named these variables with any other name.
They are not special.
Think of this grid as computer memory.
You may remember it from the previous sections.
Each cell represents a memory location and each one has a memory address.
Let's say you want to count the visits.
It can be Web site visits or you need to count records in a database.
It isn't important now.
So we declare and initialize a byte variable like so of course for a counter.
It is better to declare it with an int type so that it can represent more values.
However for now I use the byte type because each memory cell represents one byte here so it is easier
for me to explain the pointers to you.
So what happens when you declare a variable.
You know the answer.
It allocates space on the memory.
Like so here the variable's memory location is 6.
Or in other words, its memory address is 6 and its value is hundreds.
Because I have initialize it with a hundred so far so good.
Now let's talk about pointers.
I'll explain why you need them later on but for now let's understand the concept of pointers.
In Go, you can find the address of a variable like so the ampersand is an address operator you need to
type it right before a value to find its memory address.
Here I use it to find the memory address of the counter variable.
It returns us to memory address 6.
So what can you do with it.
For example you can store it in a pointer variable like so here I have assigned the memory address of
the counter variable to the p variable variable p is a pointer variable because it stores a memory address
if you want to.
You can assign it a different memory address if you want to, or you can pass it to functions and so on. It as an
ordinary variable but it's a pointer variable.
The only difference is that it stores a memory address by the way.
There is fundamental knowledge that you need to be aware of. In Go, pointers have types too.
Actually there is a corresponding pointer type for every type automatically.
So what is the type of the variable p.
Since it stores the memory address of a byte variable its type looks like this.
You can read it like so a pointer to a byte value so you can only store the memory address of a byte
value in it.
You cannot store the memory address of any other type in it the pointer a variable p knows the address
of the counter variable.
Right.
So this means it can find the value of the counter variable too.
To do that.
You can use the indirection operator like so like the address operator you need to type it right before
a pointer value here variable p is a pointer variable so you need to type the indirection operator right
before it.
So what happens when you do so? As I've said, it finds the value of the counter variable. It's because the variable
p points to the counter variable's address.
You can also save the result to a variable like so so what is the type of variable v here.
Well it's just another byte variable like the counter variable its type is byte because star P returns
you the value inside the counter variable.
That's why it is called indirection Operator Please never forget star byte is a pointer type.
It says that it's a byte pointer.
However star P is the indirection operator.
So there is an important difference between them.
So when you add a star before a type it becomes a pointer type.
However when you type it before a pointer value it returns you the referenced value.
This was a simple explanation actually.
Now let's take a look at what actually happens behind the scenes first.
The address operator finds the address of the counter variable like so.
After that, I save the address of the counter variable in a pointer variable.
When I do so, Go creates a pointer variable on memory. And it saves the address of the counter variable
in the variable p.
Like so.
So, the P pointer variable stores the memory address of the counter variable. As you can see, there are multiple
indirections.
The address operator finds the address and the pointer P variable stores the address in the counter
variable.
Now let's take a look at and understand how the indirection operator works.
Let's get the counter variable's value through the P pointer.
Okay now let's save it to a variable.
When I do so Go creates a new byte variable on memory.
For now it is empty.
Let's see how Go initializes it.
The indirection operator needs to find the pointer value.
So it looks for it in the P pointer variable through the pointer.
the indirection operator sees that variable "P" points to memory location 6.
So, it has got the address. Using the address, the indirection operator goes to the address. When it reaches
there.
It finds that there is a byte variable in that address.
Remember the variable counter is stored at this address.
So the indirection operator takes the value inside the variable counter and uses that value to initialize
the variable v. In the end, "V" becomes 100. As you can see the indirection operator does a lot of
things but it's a very fast operation so do not worry about its performance.
Note that V stores a copy of the counter
variable's value. So the variable counter and V are different variables.
This means that they can change independently.
Let me assign a different value to the variable v when I do so it changes the value inside the variable
v.
Please pay attention to the counter variable.
It doesn't change because the counter and V variables are different variables.
After I've assigned the V variable's value using the pointer indirection, it doesn't need to use pointer mechanics
anymore so the variable v becomes an ordinary byte variable.
It gets a byte type because the pointer variable "P" is a byte pointer. Now, let's see what happens if I
change the counter like so.
So the counter becomes 101. Let's use a pointer indirection to see what the pointer P variable
returns. It looks at the memory address that is stored in the variable p. Through that it goes to the
memory location 6 in there it finds that the counter variable contains 101.
So in the end it returns 101.
This means: A pointer variable always points to the latest updated value that it points to. Here,
it finds that the counter variable is 101 because 101 is its latest
value.
Now, let's see, what happens if you change the counter variable through the pointer variable.
Let's assign 25.
As you can see, you can also use the indirection operator on the left-side of the assignment.
Let's see how it works.
First it finds the value stored in the pointer.
It finds that the pointer variable stores the memory address.
6.
So it goes to the sixth memory address and finds the counter variable there.
Now it's time to do the assignment.
When I do so, the value inside the counter variable changes to 25. Let's see what happens
when you print the counter variable now.
Of course it prints 25 because the counter variable contains 25.
So in summary by using the indirection operator you can retrieve an updated value indirectly through
a pointer.
Here it indirectly updates the value of the counter variable.
All right let me summarize what you have learned so far.
Here is a byte pointer variable.
Its type is byte pointer because there is a star before the byte type.
Here is a byte variable. Obviously,
its type is byte.
This is how you can find the memory address of the counter variable.
The Ampersand here is called the address operator.
It returns a byte pointer value. So it returns a byte pointer type.
It's because the counter's type is byte.
You can assign the counter's address to the P pointer variable like so. You can do so because the type
of P variable and address of counter is a byte pointer.
This is how you can find the value of counter through the P pointer variable.
It is called the indirection operator.
It returns a copy of the counter's value. So it returns a byte value.
It's because the counter's type is byte.
Please pause at this moment at let's take a look at this diagram, and think about it. All right.
I have only talked about the byte pointers.
However it's not the whole picture because there is a corresponding pointer type for every other type.
Or, you can declare a struct type. When you do so
There happens a corresponding struct pointer type like so or there are pointer types for errors as well
and so on.
All right.
That's all for now.
See you in the next lecture.