Welcome back.
You've learned what happens when a method receives a value.
But what happens when it receives a pointer instead.
First of all I'm going to reorganize this code a little bit more.
I'm going to group and put each variable on a single line so I can show you more code without scrolling
up and down OK better before talking about pointer receivers.
Let's take a look at an example.
As you can see you can run methods using a value for example you can print a book value using the print
method here.
Go automatically passes the book value to the print method.
There is one more way to run a method since a method belongs to a type.
You can also run it using its type.
Remember game is not a value but a type. Voila!
The print method is here.
Let's run it.
Hold on.
It doesn't work because now the print method doesn't know which game value that it should use.
When you run a method to using a type you need to send a value of that type to the method as the first
argument.
For example I can say use minecraft or I can say use Tetris.
Let's run the print method through the book type with a book value.
I'm going to say use Moby Dick.
You run a method through a type it is called a method expression.
So these are called Method expressions.
Anyway let's try it it works.
But why does it work? To understand that you need to learn how a method really works behind the scenes
and method exactly looks and works like a function.
For example the print method looks like this as you can see receivers are not magical entities.
So you can run the print method on a book value like so you don't usually see this happening but behind
the scenes go automatically passes
Moby Dick variable to the method as the first argument or you can also manually sent the receiver value
using the book type as you can see in this case you need to provide the book value as an argument by
yourself.
Therefore in both cases the printing method receives a copy of Moby Dick.
You can run a method either way but we usually run it using a value I explained you this because
I want you to deeply understand how a method really works in summary a method is a function that takes
a receiver as the first argument.
Technically there is only one difference between a method and a function. A method belongs to a type.
However a function belongs to a package now that you understand what a method really is.
I can remove this code.
OK now we can talk about pointer receivers.
Let's say you want to make a discount on game prices.
To do that I'm going to add a discount method to the game type.
It takes a discount ratio let's discount the game price like so as you can see I can use the game value
inside the method because I've got it as a receiver.
OK let's go to the main function and use the discount method there.
Here I'm going to discount the Minecraft by 50 percent.
Let's run it.
Let's check out the Minecraft.
The price hasn't changed.
It is still 20 dollars not 10 dollars.
Let's see what's going on.
Let's go back to the game type here.
We assume that we can access to the minecraft variable through the receiver.
So let's print it and understand what's going on let's run it after 50 percent discount the game price
becomes 10 dollars.
However the discount is only applied here.
It's because the receiver is a copy of the original Minecraft variable.
Let me remove the debugging code from here.
This is the discount method we wrote earlier.
It has a value receiver let's run it using the Minecraft the Minecraft becomes a receiver in the discount
method.
The problem is that the variable G.
Here is a copy.
So changing the price of the copy won't change the price of the original Minecraft variable here is
a quick question.
What would you do if you want to change an input parameter inside a function you would use a pointer.
Right?
You learned that a method is just a function.
Therefore I can fix the problem by changing the receiver type to a pointer.
Let's rerun the discount method.
Now the receiver is a pointer to the original Minecraft so the receiver variable G becomes a pointer
to Minecraft changing the price field of the receiver will change the original Minecraft variable as
well.
Okay let's start by changing the discount method to a pointer receiver as you can see G is a pointer
to a game value now.
Okay let's try it nice now it works.
But I didn't send a pointer to the discount method. So, how could it change the original Minecraft?
How could it receive a pointer?
Let me explain.
Here Go sees that the discount method has a pointer receiver so it automatically takes the address
of the Minecraft variable like so let me run it.
So this is what happens behind the scenes when a method has a pointer receiver Go takes its address
automatically.
Let me take it back.
Let me tell you one more thing here.
When one of the methods takes a pointer a receiver it is better to convert all the methods to pointer
receivers.
It doesn't matter whether they need to change the original value or not.
You will see why this is necessary to do so.
When I talk about interfaces later in this section. So I'm going to change the print method to a pointer
receiver as well.
for the book type.
You don't need to do anything else it doesn't change the book value so the print method doesn't have
to be a pointer receiver.
There is one more reason for using a pointer receiver.
You learned that a method with a value receiver always copy is the receiver when it executes let me show
you what happens when you receive a large value.
First I'm going to create a new file
and I'm going to create a new struct here.
It will hold an array with 10 million games this data roughly corresponds to 200 megabytes let's create
a method that gives us the address of the receiver.
I'm just gonna print the address of the receiver.
Let's go back to the main function here.
I'm going to create a variable of the huge type this variable occupies around two hundred megabytes
of memory.
Now I'm going to make the situation more difficult by calling the addr method 10 times
let's try it.
I don't know whether it exists on your operating system but there is a program called the time it returns
the total execution time of a command.
So I'm going to run the program with the time tool. As you can see it is very slow.
It takes seconds.
Also note that each time I call the addr method it copies the h variable.
Remember a method with a value receiver copies the received value.
That's why the receiver's memory address changes 200 megabytes of data are being copied each time I call
the method.
Now let's change the value receiver to a pointer receiver.
Now the age variable becomes a pointer.
I don't have to take its address anymore.
OK let's try it.
Wow.
Now it runs in a couple of milliseconds.
It is way faster than the value receiver version.
It's because every time it is called it only copies a tiny pointer data.
As you can see the receiver address always points to the same memory location.
In summary: Use a pointer receiver when you want to change the receiver variable or use a pointer receiver
when the received value is very large.
Picking the right receiver type confuses beginners.
Most of the time they cannot decide whether to use a pointer receiver or a value receiver.
Fortunately now you understand when the use a pointer receiver see you in the next lecture.