1 00:00:00,000 --> 00:00:04,600 So, fairly important topic in general is comparison. What can be 2 00:00:04,600 --> 00:00:08,600 compared to something else? What can we use equally? Cause and not equals with, 3 00:00:08,600 --> 00:00:12,800 and within go, there's a concept of a comparable type and I'm 4 00:00:12,800 --> 00:00:16,900 going to take you through what things are comparable and what are not. So some very 5 00:00:16,900 --> 00:00:20,500 obvious, basic things are comparable. So let's just start with some 6 00:00:20,500 --> 00:00:24,800 numbers. So if we said, we had an integer that was 42 and another 7 00:00:24,800 --> 00:00:28,600 one that was 43, are those things comparable will clearly. They are they're integers. 8 00:00:28,600 --> 00:00:29,800 And 9 00:00:30,000 --> 00:00:34,500 Going to use % T to say whether they're equal. So, simple 10 00:00:34,500 --> 00:00:38,800 comparison, these are just two integers and we go up here. Well, no, 11 00:00:38,800 --> 00:00:42,900 they're not because they're 42 and 43. And clearly, if they were the same, 12 00:00:42,900 --> 00:00:46,800 then they beat the same. So that's your basic equals equals and of course, there is 13 00:00:47,000 --> 00:00:51,700 not equals bang equals for not equals. Now, what if we had 14 00:00:51,700 --> 00:00:55,600 specific types on these? So let's suppose we had I as an 15 00:00:55,600 --> 00:00:59,800 intent and was going to be equal to 42 and J is an 8-bit. 16 00:01:00,000 --> 00:01:04,900 Cher is equal to 42 as well. So here you have a problem. This is a 17 00:01:04,900 --> 00:01:08,800 compile-time error that those things are not comparable because the types are completely different. 18 00:01:09,100 --> 00:01:13,900 So the types have to be the same once the types of the same. Then it's a common question of 19 00:01:13,900 --> 00:01:17,800 whether they can actually be compared. So for example, clearly 20 00:01:17,800 --> 00:01:21,700 integers have a comparison function on them as do other 21 00:01:21,800 --> 00:01:24,800 basic types. So for example, let's have a couple of strings 22 00:01:26,700 --> 00:01:28,000 this is how this, this, 23 00:01:30,800 --> 00:01:32,700 And let's see if these are the same. 24 00:01:35,000 --> 00:01:39,400 Don't know. Clearly, they're not, but they also comparable so strings. Have a simple comparison 25 00:01:39,500 --> 00:01:43,700 operations on them, but other more complex types are also comparable. So 26 00:01:44,000 --> 00:01:48,900 for example, it's possible to have struts that are compared. 27 00:01:48,900 --> 00:01:51,100 So let's just start with a simple struct like this. 28 00:01:52,900 --> 00:01:56,700 I've kind of done this one before so we have this is my string which 29 00:01:56,700 --> 00:02:00,900 maybe have some interesting methods on it and I'm going to create a couple of those. So I'm going 30 00:02:00,900 --> 00:02:04,600 to say my string and just 31 00:02:04,600 --> 00:02:07,600 extra to hello. And 32 00:02:16,800 --> 00:02:18,500 Do the same operation on those. 33 00:02:20,100 --> 00:02:24,800 And though they're not the same so as you can see these trucks have been compared. Now 34 00:02:24,800 --> 00:02:28,900 the way in which structure comparison works and go is that structs can be compared 35 00:02:29,000 --> 00:02:33,900 if all the types within them can be compared. So for example, I could have strings in 36 00:02:33,900 --> 00:02:37,900 here and introduce other even other struct. So as long as we were able to 37 00:02:37,900 --> 00:02:41,600 compare all the things that were in them, so that that 38 00:02:41,600 --> 00:02:45,900 works well. Now, you can also compare interfaces so you can go 39 00:02:45,900 --> 00:02:49,800 in and you can say two things with the same interface are they, are they the same? So you 40 00:02:50,200 --> 00:02:52,400 Have my interface. 41 00:02:53,800 --> 00:02:57,100 Interfaces and you could have some function in here. 42 00:02:58,600 --> 00:03:02,700 Like this as or anything of that type could 43 00:03:02,700 --> 00:03:06,900 be could be compared. So you can say interface like this and then 44 00:03:07,000 --> 00:03:09,200 sorry, I'm sorry my interface. 45 00:03:11,000 --> 00:03:14,000 and so on, you could let's just try to of these 46 00:03:19,700 --> 00:03:23,600 So those two obviously the same interface completely but you can equally 47 00:03:23,600 --> 00:03:27,500 compare something that had for example a string within it and see if it was 48 00:03:27,600 --> 00:03:31,700 exactly the same interface as mind face. So you can do basic types 49 00:03:31,800 --> 00:03:35,800 struct and interface comparisons and one of the reasons why 50 00:03:35,800 --> 00:03:39,900 interface comparisons as re y comparisons, General are important is because 51 00:03:39,900 --> 00:03:43,800 if you're using a map in go, then the map 52 00:03:43,800 --> 00:03:46,200 type that can be used for the keys. 53 00:03:46,400 --> 00:03:50,400 To be something that can be compared and it can be useful because you can 54 00:03:50,400 --> 00:03:54,900 create a type for example, a structure and use it in a map. So 55 00:03:55,400 --> 00:03:59,100 let's suppose I had something like a person struct 56 00:03:59,800 --> 00:04:03,600 and this is going to have a first name and a last name this 57 00:04:03,600 --> 00:04:07,700 person and this was I created a map of these 58 00:04:07,700 --> 00:04:11,800 things. So for example, I can go into here and I can 59 00:04:11,800 --> 00:04:13,600 say people, 60 00:04:15,600 --> 00:04:19,500 And let's make ourselves a map from from a person 61 00:04:20,000 --> 00:04:24,600 to a Boolean and the Boolean is going to say whether they're a 62 00:04:24,600 --> 00:04:28,800 child or not and then I can insert into my map. 63 00:04:30,300 --> 00:04:34,100 A person and let's just say 64 00:04:35,900 --> 00:04:36,300 me. 65 00:04:42,800 --> 00:04:46,900 And I am an adult now. Become another person. 66 00:04:48,400 --> 00:04:52,600 Let's see, who should we have as a child? Well, let's go Justin 67 00:04:52,600 --> 00:04:56,800 Bieber and I'm going to say, not an adult might not be quite 68 00:04:56,800 --> 00:05:00,900 accurate, so we can, we can build ourselves a map like this. And 69 00:05:00,900 --> 00:05:04,600 this should allow us to do comparisons without any problem. It's 70 00:05:04,600 --> 00:05:08,900 Miss, obviously, we've not used for my, let's just print print out the whole thing. 71 00:05:13,000 --> 00:05:17,400 So there you go. So now you see this entire map? And because the 72 00:05:17,800 --> 00:05:21,800 map key person was something that could be compared, it can be used 73 00:05:21,800 --> 00:05:25,800 in the key of a map and the reason that's interesting is 74 00:05:25,800 --> 00:05:29,700 that in some other language you might find yourself having to flatten out 75 00:05:29,700 --> 00:05:33,900 the structures to make them into Strings, but you have to have some function that converts them here. You can just say 76 00:05:33,900 --> 00:05:37,800 this is comparable, you can use it. The one big thing that is 77 00:05:37,800 --> 00:05:41,600 incomparable is a slice. You can't take a slice and compare it to another 78 00:05:41,600 --> 00:05:42,000 one. 79 00:05:42,700 --> 00:05:46,900 Even if it points to the same, underlying array, comparison is not defined on slices, 80 00:05:46,900 --> 00:05:49,700 but for pretty much everything else, it is available. 81 00:05:54,300 --> 00:05:58,900 Now in this example, I use this person struct for the keys in the map and I 82 00:05:58,900 --> 00:06:02,600 had a Boolean storing whether they were an adult or a child 83 00:06:03,000 --> 00:06:07,800 and quite a common use of maps is to use them as sets where you don't really need a 84 00:06:07,800 --> 00:06:11,700 true or a false value in there. You just need that thing to exist or not. So 85 00:06:11,900 --> 00:06:15,800 one very common way to do that is to use an anonymous empty strap. 86 00:06:15,800 --> 00:06:19,900 So you could do something like this. So you can say I'm a 87 00:06:19,900 --> 00:06:23,300 person to an empty struct and then you can, you can use that 88 00:06:24,700 --> 00:06:26,600 Like this. So you can just say, 89 00:06:28,600 --> 00:06:29,700 Just make one of those. 90 00:06:31,900 --> 00:06:32,500 Like that. 91 00:06:33,800 --> 00:06:37,900 And if you notice, there's got to be some syntax here. So here you've got an empty Anonymous struct. You 92 00:06:37,900 --> 00:06:41,900 haven't given any type. If you really wanted to you could give it a type named, like empty or 93 00:06:42,400 --> 00:06:46,900 non-existent. And for each person, I've just instantiated one of those. So, here's 94 00:06:46,900 --> 00:06:50,900 the type empty struct and it's empty. As can look a little 95 00:06:50,900 --> 00:06:54,900 bit odd that syntax, but this means that the map is literally just 96 00:06:54,900 --> 00:06:58,900 being used a bit like a set. And so, for example, I can go in here and I 97 00:06:58,900 --> 00:07:02,800 can ask myself if a person is in the set. So, let's just do 98 00:07:02,800 --> 00:07:03,300 that. 99 00:07:05,600 --> 00:07:06,600 so, I'm going to say, 100 00:07:10,200 --> 00:07:14,700 use the okay for looking at him map value and say in people, 101 00:07:15,300 --> 00:07:17,900 is there a person called 102 00:07:22,100 --> 00:07:23,000 Adam Smith. 103 00:07:24,500 --> 00:07:28,700 And we'll just say, print out the okay value so we'll find out does that person 104 00:07:28,700 --> 00:07:32,700 exists within that? That's at and no there isn't 105 00:07:32,800 --> 00:07:34,300 and just to make sure it works. 106 00:07:40,300 --> 00:07:41,300 I can spell diva. 107 00:07:43,100 --> 00:07:47,500 Yes, he's present in the set so that's using the map as a set 108 00:07:47,700 --> 00:07:51,800 with this complex type as the key value. Another thing you might 109 00:07:51,800 --> 00:07:55,900 want to do, sometimes it's useful to have both set a set 110 00:07:55,900 --> 00:07:59,900 value. Is it present or not and also a Boolean value. So for 111 00:07:59,900 --> 00:08:03,900 example you may be iterating through something, building up a list of 112 00:08:03,900 --> 00:08:07,900 this was this was present or not. This had this value or not and you want to have 113 00:08:07,900 --> 00:08:11,900 essentially Tri-State thing, you want to have it, is it present? Is it real? Or not? 114 00:08:11,900 --> 00:08:12,800 And so, the way I will try 115 00:08:12,900 --> 00:08:15,900 Like to do that is to go back to that being a Boolean. 116 00:08:18,900 --> 00:08:22,700 So let's say, let's say would you go back to the adult child thing, true 117 00:08:22,700 --> 00:08:26,100 false and then we can pull out both 118 00:08:26,400 --> 00:08:30,800 presence in the set with the okay and also the truth value. So you can say 119 00:08:30,800 --> 00:08:34,600 something like that and then we can look at okay when you say if okay 120 00:08:34,600 --> 00:08:38,800 then print out the truth value and 121 00:08:38,800 --> 00:08:42,900 it wasn't there then obviously we would we would print out the website 122 00:08:42,900 --> 00:08:46,900 was not present so we just run that we get false because Justin Bieber is in 123 00:08:46,900 --> 00:08:48,500 the set and for 124 00:08:48,600 --> 00:08:49,200 Go here. 125 00:08:55,200 --> 00:08:56,400 Present. And it's just 126 00:08:58,100 --> 00:09:02,700 Spell his name wrong and so we find out that that person is not present. So there you've both 127 00:09:02,700 --> 00:09:06,900 got. You can tell whether something is in the set by using the okay form. And you 128 00:09:06,900 --> 00:09:10,600 can also put a Boolean value there. Sometimes that is a handy, kind of Tri-State 129 00:09:10,600 --> 00:09:11,100 trick. 130 00:09:15,400 --> 00:09:19,900 So I said before that, one of the things you can do with map Keys is putting them anything that's 131 00:09:19,900 --> 00:09:23,800 comparable and that one of the things that comparable is an interface and 132 00:09:23,800 --> 00:09:27,900 so you can use an interface for a map key, which has some 133 00:09:27,900 --> 00:09:31,600 quite interesting uses. I'm going to produce a little program here, which will 134 00:09:31,600 --> 00:09:35,900 use an IO writer as the map key and you can put in it. Anything that 135 00:09:35,900 --> 00:09:39,900 supports that interface and then use that to have a set of 136 00:09:40,100 --> 00:09:44,800 outputs that we can turn on or off as we want by having the map, go from a writer 137 00:09:45,000 --> 00:09:49,900 To a Boolean which indicates whether that is available for writing to at the moment. So 138 00:09:49,900 --> 00:09:53,700 it's very simple to declare that it's just call it output and we just 139 00:09:53,700 --> 00:09:57,600 make a map that goes from an IO writer to a Boolean, just like that. So the 140 00:09:57,600 --> 00:10:01,500 interface as the map key. And obviously I'm going to need I over that 141 00:10:02,100 --> 00:10:06,100 and then I can put in that some simple things. So let's start by saying 142 00:10:06,600 --> 00:10:10,900 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 143 00:10:10,900 --> 00:10:12,200 need OS for that. 144 00:10:13,200 --> 00:10:17,600 And let's just do play that and say, standard error, for the moment will be disabled. 145 00:10:18,800 --> 00:10:22,700 I will make ourselves a simple Loop will Loop through that map, all the keys and write 146 00:10:22,800 --> 00:10:26,900 something to those outputs based on whether they're enabled or not. So 147 00:10:27,200 --> 00:10:31,400 we can say w is the writer enabled is the Boolean 148 00:10:31,400 --> 00:10:35,600 part range over the output and then 149 00:10:35,600 --> 00:10:39,600 if if it's enabled then we'll use 150 00:10:39,600 --> 00:10:43,600 fprintf which can go to an IO writer to that W, which is the actual 151 00:10:43,600 --> 00:10:46,000 writer. And we'll just say some output. 152 00:10:50,100 --> 00:10:54,500 So that will create this map from IO writers to Bull 153 00:10:55,000 --> 00:10:59,300 put standard out and standard error in only standard out is enabled range through them if 154 00:10:59,300 --> 00:11:02,700 enabled print some output to that. So let's just run that 155 00:11:04,700 --> 00:11:08,900 Some output came out and that came out in fact on the standard out and we could we could sort of 156 00:11:08,900 --> 00:11:12,400 verify that by making it go away like that 157 00:11:12,700 --> 00:11:16,400 and we could flip around. Let's just say that. In fact, it was 158 00:11:16,700 --> 00:11:20,200 standard error. That was enabled. Then oh, look at that actually came out and didn't get 159 00:11:20,200 --> 00:11:24,400 redirected and anything. That's an IO, writer can be here, not just these OS things. 160 00:11:24,700 --> 00:11:28,900 So let's include the bike offers. So we go into 161 00:11:28,900 --> 00:11:32,800 here and we're going to make ourselves a new buffer, which is the quickest way is 162 00:11:32,800 --> 00:11:33,700 like that. 163 00:11:34,400 --> 00:11:38,800 And the buffer actually has supports, right? We can just check 164 00:11:38,800 --> 00:11:39,200 that. 165 00:11:41,400 --> 00:11:45,400 So if you have a look down in the documentation, you'll see 166 00:11:45,900 --> 00:11:49,400 that there is is the buffer type 167 00:11:49,600 --> 00:11:53,900 and it has it right function, right here. And this is what it 168 00:11:53,900 --> 00:11:57,900 needs to support Iota. Write a decent IO writer, so we can 169 00:11:57,900 --> 00:12:01,900 do that and we can add that and 170 00:12:01,900 --> 00:12:05,900 will enable that. So it's going to get written into that buffer and just to make sure at the end 171 00:12:05,900 --> 00:12:09,200 something really got written. Let's just say 172 00:12:11,000 --> 00:12:15,900 Find out how many bytes got written into their use the length, the length function on the, 173 00:12:16,300 --> 00:12:20,000 on the buffer and which down for that. 174 00:12:21,600 --> 00:12:25,800 So, some output came out that was because of standard error and 12. Bytes were 175 00:12:25,800 --> 00:12:29,800 written to the buffer by that and just for the fun of it. Let's just run all of them at the 176 00:12:29,800 --> 00:12:30,600 same time. 177 00:12:31,800 --> 00:12:35,900 There you go. The standard out and standard error and writing to the buffer. So anything 178 00:12:35,900 --> 00:12:39,900 that's an interface can also be a map key and that can be extremely useful in some circumstances.