Hi.
This is the sixth video of this section pointers structures and interfaces in the previous video.
We looked at arrays slices and maps in this video.
We will learn to declare pointers use and print the values from a pointer.
Then we will see how to declare and use structures and at the end we will explore about interfaces pointers
are the number one source of the headache of every C or C++ programmer but they are one of the main
tools to achieve high performance codes in non garbage collected languages.
Fortunately for us goes pointers have achieved the best of both worlds by providing high performance
pointers with garbage collector capabilities and easiness.
On the other side for its detractors go lax inheritance in favor of composition pointers are hated loved
and very useful at the same time to understand what a pointer is can be difficult.
So let's try with a real world explanation.
As we mentioned earlier in this section a pointer is like a mailbox.
Imagine a bunch of mailboxes in a building.
All of them have the same size and shape but each refers to a different house within the building.
Just because all the mailboxes are the same size does not mean that each house will have the same size.
So the pointers are the mailboxes all of them of the same size and that refer to a house.
The building is our memory and the houses are the types our pointers refer to and the memory they allocate.
If you want to receive something in your house it it's far easier to simply send the address of your
house instead of sending the entire house so that your package is deposited inside but they have some
drawbacks as if you send your address and your house disappears after sending or its type owner change.
You'll be in trouble.
How is this useful.
Imagine that somehow you have a four gigabytes of data in a variable and you need to pass it to a different
function without a pointer the entire variable is cloned to the scope of the function that is going
to use it.
So you'll have eight gigabytes of memory occupied by using this variable twice that hopefully the second
function isn't going to use in a different function again to raise this number even more.
You could use a pointer to pass a very small reference to this chunk to the first function so that just
the small reference is cloned and you can keep your memory usage low.
While this isn't the most academic nor exact explanation it gives a good view of what a pointer is without
explaining what a stack or a heap is or how they work in X 86 architectures.
Pointers and go are very limited compared to C or C++ pointers.
You can't use pointer arithmetic nor can you create a pointer to reference an exact position in the
stack pointers and go can be declared like this here.
No Cole on equal to 5 code represents our 4 gigabyte variable and pointer to number contains the reference
represented by an ampersand to this variable.
It's the direction to the variable let's print the variable point to number which is a simple variable.
So let's run this.
What's that number.
Well the direction to our variable memory and how can I print the actual value of the house.
Well with an asterisk we tell the compiler to take the value that the pointer is referencing which is
our 4 gigabyte variable as you can see we got the output as 5.
Now let's move on to struct a struct is an object and go it has some similarities with classes in P
as they have fields struct can implement interfaces and declare methods.
But for example in go there is not inheritance lack of inheritance looks limiting but in fact composition
over inheritance was a requirement of the language to declare a structure.
You have to prefix its name with the keyword type and suffix with the keyword struct and then you declare
any field or method between brackets.
For example let me show you a piece of code in this piece of code.
We have declared a person structure with three public fields that is name surname and Hobbes and one
private field I.D..
If you recall the visibility part in this section lowercase fields and go refers to private fields that
are just visible within the same package.
With this struct we can now create as many instances of person as we want.
Now will write a function called get full name that will give the composition of the name and the surname
of the struct it belongs to.
Let's add this function.
Methods are defined similarly to functions in a slightly different way.
There is a person asterisk person that refers to a pointer to the created instance of the struct.
It's like using the keyword.
This in Java or self in Python when referring to the pointing object.
Maybe you are thinking why does person asterisk person have the pointer operator to reflect that P is
actually a pointer and not a value.
This is because you can also pass person by value by removing the pointer signature.
In which case a copy of the value of person is passed to the function.
This has some implications for example any change that you make in P if you pass it by value won't be
reflected in source P but what about our get full name method.
It's console output has no effect in appearance but a full copy was passed before evaluating the function.
But if we modify person here the source person won't be affected and the new person value will be available
only on the scope of this function.
On the main function we create an instance of our structure called P.
As you can see we have used implicit notation to create the variable that is the colon equal to symbol
to set the fields.
We have to refer to the name of the field colon the value and the comma.
Don't forget the comma at the end to access the fields of the instantiated structure.
We just refer to them by their name like P. dots name or P. dot Hobbes.
You use the same syntax to access the methods of the structure like p dot get full name.
Here's the output of this program.
Structures can also contain another structure or composition and implement interface methods apart from
their own.
But what's an interface method.
That's what we'll be discussing next.
Interfaces are essential in object oriented programming in functional programming and especially in
design patterns go source code is full of interfaces everywhere because they provide the abstraction
needed to deliver uncoupled code with the help of functions as a programmer.
You also need this type of abstraction when you write libraries but also when you write code that is
going to be maintained in the future with new functionality.
Interfaces are something difficult to grasp at the beginning but very easy.
Once you have understood their behavior and provide very elegant solutions for common problems we will
use them extensively during this course.
So put special focus on this part of this video.
An interface is something really simple but powerful.
It's usually defined as a contract between the objects that implement it.
But this explanation isn't clear enough in my honest opinion for newcomers to the interface world.
A water pipe is a contract to whatever you pass through it must be a liquid.
Anyone can use the pipe and the pipe will transport whatever liquid you put in it without knowing the
content.
The water pipe is the interface that enforces that the users must pass liquids and not something else.
Let's think about another example.
A train.
The railroads of a train are like an interface.
A train must construct that is implement its width with a specified value so that it can enter the railroad.
But the railroad never knows exactly what it's carrying passengers or cargo.
So for example let's see the aspect of an interface of the railroad.
Let me open the main dot go file and here's the railroad white checker interface.
Now the railroad wide checker is the type our trains must implement to provide information about their
with the trains will verify that the train isn't too wide or too narrow to use its railroads.
And here's the code for this logic the railroad is implemented by an imaginary station object that contains
the information about the width of the railroads in this station and that has a method to check whether
a train fits the needs of the railroad with the is correct sized train method.
The is correct sized train method receives an interface object which is a pointer to a train that implements
this interface and returns a validation between the width of the train and the railroad now we have
created a passenger's train.
It has a field to contain its with and implements our check rails with interface method.
The structure is considered to fulfill the needs of the railroad wide checker interface because it has
an implementation of the methods that the interfaces ask for.
So now we create a railroad of 10 units wide and two trains one of 10 units wide that fit the railroad
size and another of 15 units that cannot use the railroad.
Let's dissect this main function.
First we created a railroad object of 10 units called railroad.
Then two trains of 10 and 15 units with four passengers and cargo respectively.
Then we pass both objects to the railroad method that accepts interfaces of the railroad wide checker
interface.
The railroad itself does not know the width of each train separately but it has an interface that trains
must implement so that it can ask for each with and return a value telling you if the train can or cannot
use the railroads.
Finally let's check the output of the call to print a function so move back to the terminal and run
the command go run main dot go as I mentioned earlier.
Interfaces are so widely used during this book that it doesn't matter if it still looks confusing for
the reader as there will be plenty of examples during this course.
In this video we saw how to use pointers structures and interfaces.
In the next video we will learn about testing and TDD.