So, fairly important topic in general is comparison. What can be
compared to something else? What can we use equally? Cause and not equals with,
and within go, there's a concept of a comparable type and I'm
going to take you through what things are comparable and what are not. So some very
obvious, basic things are comparable. So let's just start with some
numbers. So if we said, we had an integer that was 42 and another
one that was 43, are those things comparable will clearly. They are they're integers.
And
Going to use % T to say whether they're equal. So, simple
comparison, these are just two integers and we go up here. Well, no,
they're not because they're 42 and 43. And clearly, if they were the same,
then they beat the same. So that's your basic equals equals and of course, there is
not equals bang equals for not equals. Now, what if we had
specific types on these? So let's suppose we had I as an
intent and was going to be equal to 42 and J is an 8-bit.
Cher is equal to 42 as well. So here you have a problem. This is a
compile-time error that those things are not comparable because the types are completely different.
So the types have to be the same once the types of the same. Then it's a common question of
whether they can actually be compared. So for example, clearly
integers have a comparison function on them as do other
basic types. So for example, let's have a couple of strings
this is how this, this,
And let's see if these are the same.
Don't know. Clearly, they're not, but they also comparable so strings. Have a simple comparison
operations on them, but other more complex types are also comparable. So
for example, it's possible to have struts that are compared.
So let's just start with a simple struct like this.
I've kind of done this one before so we have this is my string which
maybe have some interesting methods on it and I'm going to create a couple of those. So I'm going
to say my string and just
extra to hello. And
Do the same operation on those.
And though they're not the same so as you can see these trucks have been compared. Now
the way in which structure comparison works and go is that structs can be compared
if all the types within them can be compared. So for example, I could have strings in
here and introduce other even other struct. So as long as we were able to
compare all the things that were in them, so that that
works well. Now, you can also compare interfaces so you can go
in and you can say two things with the same interface are they, are they the same? So you
Have my interface.
Interfaces and you could have some function in here.
Like this as or anything of that type could
be could be compared. So you can say interface like this and then
sorry, I'm sorry my interface.
and so on, you could let's just try to of these
So those two obviously the same interface completely but you can equally
compare something that had for example a string within it and see if it was
exactly the same interface as mind face. So you can do basic types
struct and interface comparisons and one of the reasons why
interface comparisons as re y comparisons, General are important is because
if you're using a map in go, then the map
type that can be used for the keys.
To be something that can be compared and it can be useful because you can
create a type for example, a structure and use it in a map. So
let's suppose I had something like a person struct
and this is going to have a first name and a last name this
person and this was I created a map of these
things. So for example, I can go into here and I can
say people,
And let's make ourselves a map from from a person
to a Boolean and the Boolean is going to say whether they're a
child or not and then I can insert into my map.
A person and let's just say
me.
And I am an adult now. Become another person.
Let's see, who should we have as a child? Well, let's go Justin
Bieber and I'm going to say, not an adult might not be quite
accurate, so we can, we can build ourselves a map like this. And
this should allow us to do comparisons without any problem. It's
Miss, obviously, we've not used for my, let's just print print out the whole thing.
So there you go. So now you see this entire map? And because the
map key person was something that could be compared, it can be used
in the key of a map and the reason that's interesting is
that in some other language you might find yourself having to flatten out
the structures to make them into Strings, but you have to have some function that converts them here. You can just say
this is comparable, you can use it. The one big thing that is
incomparable is a slice. You can't take a slice and compare it to another
one.
Even if it points to the same, underlying array, comparison is not defined on slices,
but for pretty much everything else, it is available.
Now in this example, I use this person struct for the keys in the map and I
had a Boolean storing whether they were an adult or a child
and quite a common use of maps is to use them as sets where you don't really need a
true or a false value in there. You just need that thing to exist or not. So
one very common way to do that is to use an anonymous empty strap.
So you could do something like this. So you can say I'm a
person to an empty struct and then you can, you can use that
Like this. So you can just say,
Just make one of those.
Like that.
And if you notice, there's got to be some syntax here. So here you've got an empty Anonymous struct. You
haven't given any type. If you really wanted to you could give it a type named, like empty or
non-existent. And for each person, I've just instantiated one of those. So, here's
the type empty struct and it's empty. As can look a little
bit odd that syntax, but this means that the map is literally just
being used a bit like a set. And so, for example, I can go in here and I
can ask myself if a person is in the set. So, let's just do
that.
so, I'm going to say,
use the okay for looking at him map value and say in people,
is there a person called
Adam Smith.
And we'll just say, print out the okay value so we'll find out does that person
exists within that? That's at and no there isn't
and just to make sure it works.
I can spell diva.
Yes, he's present in the set so that's using the map as a set
with this complex type as the key value. Another thing you might
want to do, sometimes it's useful to have both set a set
value. Is it present or not and also a Boolean value. So for
example you may be iterating through something, building up a list of
this was this was present or not. This had this value or not and you want to have
essentially Tri-State thing, you want to have it, is it present? Is it real? Or not?
And so, the way I will try
Like to do that is to go back to that being a Boolean.
So let's say, let's say would you go back to the adult child thing, true
false and then we can pull out both
presence in the set with the okay and also the truth value. So you can say
something like that and then we can look at okay when you say if okay
then print out the truth value and
it wasn't there then obviously we would we would print out the website
was not present so we just run that we get false because Justin Bieber is in
the set and for
Go here.
Present. And it's just
Spell his name wrong and so we find out that that person is not present. So there you've both
got. You can tell whether something is in the set by using the okay form. And you
can also put a Boolean value there. Sometimes that is a handy, kind of Tri-State
trick.
So I said before that, one of the things you can do with map Keys is putting them anything that's
comparable and that one of the things that comparable is an interface and
so you can use an interface for a map key, which has some
quite interesting uses. I'm going to produce a little program here, which will
use an IO writer as the map key and you can put in it. Anything that
supports that interface and then use that to have a set of
outputs that we can turn on or off as we want by having the map, go from a writer
To a Boolean which indicates whether that is available for writing to at the moment. So
it's very simple to declare that it's just call it output and we just
make a map that goes from an IO writer to a Boolean, just like that. So the
interface as the map key. And obviously I'm going to need I over that
and then I can put in that some simple things. So let's start by saying
standard out which of course would be a classic thing is enabled so we're going to help it stand out. So I'm going to
need OS for that.
And let's just do play that and say, standard error, for the moment will be disabled.
I will make ourselves a simple Loop will Loop through that map, all the keys and write
something to those outputs based on whether they're enabled or not. So
we can say w is the writer enabled is the Boolean
part range over the output and then
if if it's enabled then we'll use
fprintf which can go to an IO writer to that W, which is the actual
writer. And we'll just say some output.
So that will create this map from IO writers to Bull
put standard out and standard error in only standard out is enabled range through them if
enabled print some output to that. So let's just run that
Some output came out and that came out in fact on the standard out and we could we could sort of
verify that by making it go away like that
and we could flip around. Let's just say that. In fact, it was
standard error. That was enabled. Then oh, look at that actually came out and didn't get
redirected and anything. That's an IO, writer can be here, not just these OS things.
So let's include the bike offers. So we go into
here and we're going to make ourselves a new buffer, which is the quickest way is
like that.
And the buffer actually has supports, right? We can just check
that.
So if you have a look down in the documentation, you'll see
that there is is the buffer type
and it has it right function, right here. And this is what it
needs to support Iota. Write a decent IO writer, so we can
do that and we can add that and
will enable that. So it's going to get written into that buffer and just to make sure at the end
something really got written. Let's just say
Find out how many bytes got written into their use the length, the length function on the,
on the buffer and which down for that.
So, some output came out that was because of standard error and 12. Bytes were
written to the buffer by that and just for the fun of it. Let's just run all of them at the
same time.
There you go. The standard out and standard error and writing to the buffer. So anything
that's an interface can also be a map key and that can be extremely useful in some circumstances.