Empty interface says nothing.
So what is an empty interface?
Well this is an empty interface.
I'm not kidding.
It doesn't have a method.
It is completely empty.
It says nothing.
You don't need to satisfy it because it has no methods.
Every type can satisfy it so it can represent any type of value.
You can type it more concisely in a single line.
We usually use it like this.
This is the same thing.
It's still an empty interface type.
This is an empty interface value.
You can declare it like so this variable holds an empty interface value.
Let's say there is a Tetris value in it.
The Tetris variable has two methods that you can use.
Let's put it in the empty interface value.
You can no longer use the methods of the game.
The empty interface value wraps it in a hidden place so the empty interface says nothing.
Let's take a look at an example.
First I'm going to create a new directory for the next example with new main.go file.
Next I'm going to declare an empty interface variable let's assign it a slice Let's print it.
No problem.
It can store a slice.
Now let's assign it a map. Again,
no problem.
Let's assign it's a string value. No problem at all.
Lastly let's assign it a number.
There are no errors because you can store any type of value in an empty interface value.
However you cannot directly use an empty interface value in operations.
For example let's try to multiply it with a number.
It didn't work because the any variable is not a number.
It's an empty interface value.
Remember an interface value has two parts a dynamic value and a dynamic type.
So first you need to extract the dynamic value from the interface value using the dynamic type here.
The dynamic type is int because lastly I assigned it an integer so let's use an assertion to extract
the number
nice.
It works.
Now as you can see it doesn't matter what kind of value you store in an interface value.
However you want to use the dynamic value in operations.
You must first extract it from the interface value here.
The dynamic type is an integer.
So first I get it from the interface value as an integer.
Only then I can multiply it.
Now I'm going to create another directory with a new file
let's create an int slice let's create an empty interface variable.
I'm going to assign it the integer slice as you can see.
You can also assign a slice to an empty interface value.
However as I said you cannot directly use the dynamic value of an interface value.
It means you cannot use it here as a slice.
For example let's try to find the length of the slice using the empty interface variable.
Now I cannot get its length because any is an interface type.
It's not a slice type so it has no length.
However it stores an int slice.
So first I need to get the slice back from it.
Now I can get its length.
The last statement works because I'm asserting that it's an int slice.
If the dynamic type inside the interface was not an int slice my program would crash in the runtime.
This time I'm going to create a slice of empty interface values.
Why do you think? Can I assign it the nums slice?
It didn't work.
The error says you cannot assign an int slice to an empty interface slice.
It's like trying to assign the nums slice to a string slice it is the same error a type mismatch.
So what is the solution?
Well I can use a loop then I need to add the next number.
Let's print the result it works.
But why? I need to do so because the empty interface slice is not an empty interface value.
It's an empty interface slice.
That's why I need to add the numbers manually one by one to the empty interface slice.
Let's talk about this a little bit more.
The empty interface slice consists of empty interface values. The int slice consists of integer values.
The empty interface slice is a slice of empty interface values.
But it's not an empty interface value so you cannot directly assign it another type of a slice.
However, you can assign any type of value to one of its elements.
It's because each one of its elements is an empty interface value.
OK enough theory.
Let's take a look at a practical example.
First of all let me refactor this code a little bit.
I'm going to put all the variables directly into the store.
Now I can remove the store variable.
Let's go to the book type.
Let's say you need to store the publishing dates of the books to do that.
I'm going to add a field with an empty interface.
I'm going to tell you why in the main function first I'm going to add two more books.
The first book uses an integer.
The second book uses a string.
The third book doesn't have a date at all.
These are unix timestamps.
You will see how you can convert them to actual dates in a minute.
As you can see each book has a different type of publishing date.
That's why I have declared the published field as an empty interface so I can store different type of
values in it.
Let's go back to the book type here.
I'm going to print the published date.
I'm going to run it.
It doesn't look good.
I'm going to make its prey to do that.
I'm going to use a function.
It will take an empty interface value and return back a string.
I'm going to use it in the printf function. OK. Let's create the format function it takes an empty interface
and it returns a string.
For now I will simply return a string.
okay.
It works.
Let's format the dates now. As a reference,
Let's copy the book values, here.
okay the last book has no date.
So first let's check for it.
The zero value of an interface value is nil.
So if the publishing date is missing, it will be a nil value.
Only then I will say it's unknown. Otherwise, I will return an empty string. Nice. Let's format the other
dates as well.
I'm going to start with Moby Dick.
It uses an integer date so I'm going to declare an int variable and I'm going to extract the int value
using a type assertion.
If it succeeds the variable will be an integer.
So I'm going to assign to the T variable.
Now it's time to convert the integer to a time value.
To do that I'm going to call the time Unix function its last parameter is not important but it doesn't
work because the Unix function takes an int64 value.
So I need to convert the variable like so.
Now I've got a time value.
It has a string method I can use it to convert the time value to a string.
Now I can return it as well.
Okay let's try it.
It doesn't look good but it prints a more readable date.
Now let's format the last book it uses a string date.
So I'm going to extract the string value if it succeeds.
The variable will be a string.
So I need to convert it to an integer.
Good.
It works in summary.
Go allows you to write type safe code.
However the empty interface can cross that line.
Your programs can become brittle and hard to maintain.
Do not use the empty interface unless really necessary.
See you in the next lecture.