1 00:00:00,000 --> 00:00:04,900 So you will see used methods and interfaces in your own programs because they are 2 00:00:04,900 --> 00:00:08,600 the bread and butter of go. But it's worth reviewing some of the 3 00:00:08,600 --> 00:00:12,900 subtleties around pointers and values in methods, to make sure that they are 4 00:00:12,900 --> 00:00:16,700 well, understood and also is possible to have 5 00:00:16,700 --> 00:00:20,900 method values that is to take a method and treat it as a value 6 00:00:20,900 --> 00:00:24,800 in the program and sometimes that can be handy. So, to illustrate all of this, I've 7 00:00:24,800 --> 00:00:28,400 created a new package called Yelling, which has a 8 00:00:28,400 --> 00:00:29,700 type called a loud. 9 00:00:30,000 --> 00:00:34,900 String and allowed string is a string that is only ever in upper case in it. Make sure it 10 00:00:34,900 --> 00:00:38,700 is and I've added a few methods here. So I've got a simple method which is to 11 00:00:38,700 --> 00:00:42,800 create one of these things. It creates an empty one and it returns 12 00:00:42,800 --> 00:00:46,200 one here and it's not a pointer, it's just a simple 13 00:00:46,600 --> 00:00:50,800 instance of this string and then I've got a couple of methods on 14 00:00:50,800 --> 00:00:54,500 it. So the string method which coincidentally is the Stringer 15 00:00:54,600 --> 00:00:58,800 interface is going to just return the string itself. So the S is 16 00:00:58,800 --> 00:00:59,400 stored in it. 17 00:01:00,000 --> 00:01:04,900 Can call change on the string, to change the string. And that's where it actually makes sure that it's 18 00:01:04,900 --> 00:01:08,600 been uppercase to make sure it's shouting. And there's another method called blank which will 19 00:01:08,600 --> 00:01:12,700 actually blank out the string. And I've deliberately 20 00:01:12,700 --> 00:01:16,300 made a sort of error or at least done something a bit inconsistent here which is that 21 00:01:16,700 --> 00:01:20,700 here, this method is a pointer. So this method 22 00:01:20,700 --> 00:01:24,500 value here is a pointer and here it's not it's actually a copy of the 23 00:01:24,500 --> 00:01:28,700 value. So if you are call these methods on 24 00:01:29,000 --> 00:01:29,800 an instance of loud, 25 00:01:29,900 --> 00:01:33,800 String in the ones where you've got a star here, you guys are going to be piloting a pointer, 26 00:01:34,000 --> 00:01:38,600 which means you can successfully modify it. And here, you're passing a copy 27 00:01:39,100 --> 00:01:43,900 of the value and modifying. It will notify the copy you won't modify the thing 28 00:01:43,900 --> 00:01:47,400 you called with similarly here as well actually modify it 29 00:01:48,100 --> 00:01:52,800 now in general it's good to use pointer receivers like this. If the 30 00:01:52,800 --> 00:01:56,600 thing that the structure you're doing is using is large, if its 31 00:01:56,600 --> 00:01:59,800 large and copying, it would be expensive then. It's 32 00:02:00,000 --> 00:02:04,900 Not having a copy happen because when this happens you actually make a copy and in this instance it 33 00:02:04,900 --> 00:02:08,900 may be okay. A stream may be small but if it was large or the structure was complex, 34 00:02:09,100 --> 00:02:13,800 then using your point would be far better. So I'm going to use this to illustrate what happens and then make 35 00:02:13,800 --> 00:02:17,800 some changes to it. So in my program 36 00:02:17,800 --> 00:02:21,500 I'm actually importing yelling and I create one of these strings. 37 00:02:21,900 --> 00:02:25,700 I change it to hello and I printed out and so that's fairly simple. I can 38 00:02:25,700 --> 00:02:27,500 just go build this. 39 00:02:29,100 --> 00:02:33,600 And run it and it's going to say nothing at all. Now that's a surprise because you would have 40 00:02:33,600 --> 00:02:37,700 expected it to say hello all in uppercase. And the reason for that is 41 00:02:37,700 --> 00:02:41,500 that here, this is not a pointer. 42 00:02:41,900 --> 00:02:45,700 If I change this to a point now rather than copying the loud string, I'm going to get a 43 00:02:45,700 --> 00:02:49,600 pointer to it. So, let's do this and run it. And now I 44 00:02:49,600 --> 00:02:53,800 get uppercase, hello, because this lsds here 45 00:02:53,900 --> 00:02:57,800 has actually changed the underlying string. A general rule is that if 46 00:02:57,800 --> 00:02:58,600 you have 47 00:02:59,200 --> 00:03:03,800 A package like this and you've got a mixture of pointer and non 48 00:03:03,800 --> 00:03:07,800 pointer receivers. You're probably doing something a bit crazy and you should try and 49 00:03:07,800 --> 00:03:11,900 stay consistent. It should be the case that you're either accessing by copy, 50 00:03:11,900 --> 00:03:15,300 which is fine or you have pointers to things you've ever mixture, it can get very 51 00:03:15,300 --> 00:03:19,600 confusing in general. I find myself using pointers just so I don't have to think about it too 52 00:03:19,600 --> 00:03:23,900 much, the danger. Of course, it pointers is. You can get change happening underneath, 53 00:03:23,900 --> 00:03:27,500 which you may not have expected. Now, another thing you can do with 54 00:03:27,500 --> 00:03:28,700 methods is 55 00:03:29,000 --> 00:03:33,600 You can get them, it turned into water called method values, so I just 56 00:03:33,600 --> 00:03:36,900 uncomment this code and illustrate that for you. 57 00:03:37,800 --> 00:03:41,800 So here you can see that I've rather than calling loud 58 00:03:41,800 --> 00:03:45,900 string note, there's no braces here. I've just taken it as a 59 00:03:45,900 --> 00:03:49,700 value of treated that function as it on that particular function. So what's going to happen 60 00:03:49,700 --> 00:03:53,600 here is that I will be able to just call that function like that. So just a function value. 61 00:03:53,800 --> 00:03:57,400 So LS2 will be a brand new function 62 00:03:57,800 --> 00:03:58,800 and LS2 63 00:03:58,900 --> 00:04:02,900 Sorry, brand-new loud string and LS2 itself. I can do a 64 00:04:02,900 --> 00:04:06,900 similar thing notice here rather than actually calling 65 00:04:06,900 --> 00:04:10,500 change with something. I'm just taking it. So I'm taking a method as a 66 00:04:10,500 --> 00:04:14,700 value and now I can call change whenever I want. So, this is essentially 67 00:04:14,700 --> 00:04:18,700 created a closure on that particular LS2 value, and I'll be 68 00:04:18,700 --> 00:04:22,700 changing LS2. Whenever I Call change. If I just run 69 00:04:22,700 --> 00:04:23,200 this 70 00:04:25,400 --> 00:04:29,900 You'll see that happen. So be quiet, change with an LS2 and actually got 71 00:04:29,900 --> 00:04:33,900 printed out occasionally, it can be very useful to do. This one place is super 72 00:04:33,900 --> 00:04:37,300 handy, is in the net HTTP package, where you have Handler 73 00:04:37,300 --> 00:04:41,400 functions for particular routes, on a, on a web page. 74 00:04:41,600 --> 00:04:45,200 And you can actually have a structure, which is your server, or your 75 00:04:45,200 --> 00:04:49,600 context and have methods on it, which are handlers that meet the signature for a 76 00:04:49,600 --> 00:04:53,800 Handler and then just treat them as values by doing you know my server 77 00:04:53,800 --> 00:04:54,000 Dot. 78 00:04:54,300 --> 00:04:58,900 Root handle, a my server dot admin. Handlers, Etc. So don't be afraid to take a 79 00:04:58,900 --> 00:05:02,900 method as a value. There's one other slight subtle thing that happened to you. You may 80 00:05:02,900 --> 00:05:06,900 not have noticed which is that yelling dot new loud. String 81 00:05:07,000 --> 00:05:11,700 didn't return itself. A pointer returned a type in an instance of 82 00:05:11,700 --> 00:05:15,300 loud string. There's no Ampersand here. There's no star here 83 00:05:15,600 --> 00:05:19,700 yet. When I called change, for example on it, I was 84 00:05:19,700 --> 00:05:23,700 calling a pointer receiver, and go has quietly. 85 00:05:24,100 --> 00:05:28,900 Noted this what it's done is it said well this is actually really the same. As that is said, 86 00:05:28,900 --> 00:05:32,800 I'll take the address of Ls and I'll pass that over. I'll turn it into a pointer 87 00:05:32,800 --> 00:05:36,800 automatically. So that means you don't have to think about this is actually a 88 00:05:36,800 --> 00:05:38,000 pointer or not a pointer. 89 00:05:41,900 --> 00:05:45,900 Does a couple of subtle things you can do with interfaces that 90 00:05:45,900 --> 00:05:49,500 I'd like to talk about in particular, not implementing them completely 91 00:05:49,500 --> 00:05:53,600 and also verifying whether something meets a particular interface 92 00:05:53,600 --> 00:05:57,900 and you can do that by a couple of methods. I'm going to go 93 00:05:57,900 --> 00:06:01,600 into my yelling package here and I've defined 94 00:06:01,600 --> 00:06:05,900 myself and interface here to say that something is a yeller if it has 95 00:06:05,900 --> 00:06:09,700 these methods on it, so string, change blank and 96 00:06:09,700 --> 00:06:11,800 Len which will look familiar. From what 97 00:06:12,000 --> 00:06:16,800 And here, and I can use this 98 00:06:17,000 --> 00:06:21,900 perfectly normally so I just run that program doesn't make any difference as it currently is. But 99 00:06:21,900 --> 00:06:25,800 let's suppose I wanted to determine whether something like LS, 100 00:06:25,800 --> 00:06:29,800 actually was a yellow met that interface. So if you're fairly 101 00:06:29,800 --> 00:06:33,900 simple way of doing that, you define a blank variable, I want to doesn't 102 00:06:33,900 --> 00:06:36,500 exist and you say 103 00:06:38,200 --> 00:06:40,200 Of this particular interface type. 104 00:06:41,800 --> 00:06:45,900 You try to do that, you're trying to assign that thing to a particular interface and then you 105 00:06:45,900 --> 00:06:49,900 build it. And at compile time it's going to actually 106 00:06:49,900 --> 00:06:53,800 try and check the the types of that. And there's a problem 107 00:06:54,200 --> 00:06:58,000 because as it's saying here this thing 108 00:06:58,500 --> 00:07:02,600 isn't a yellow because it hasn't got the Len method. And as you may have 109 00:07:02,600 --> 00:07:06,600 noticed, I didn't actually implement the Len method so I've just implement 110 00:07:06,600 --> 00:07:07,200 it. 111 00:07:07,900 --> 00:07:12,900 This, 112 00:07:12,900 --> 00:07:16,100 I'm going here. We'll just make this turning into 113 00:07:19,500 --> 00:07:23,900 I'll pray exciting method and let's build it again and now he 114 00:07:23,900 --> 00:07:27,800 builds correctly. So verifies that, that particular interface is something 115 00:07:27,800 --> 00:07:31,900 that loud string actually. Implements completely obviously don't have to 116 00:07:31,900 --> 00:07:35,900 do that for your own interfaces. You could go in here and say, by the way, is it 117 00:07:35,900 --> 00:07:39,300 a format Stringer? So remember that implemented? 118 00:07:41,100 --> 00:07:44,100 Actually, let's look at the Stringer interface. See what it actually is. 119 00:07:47,000 --> 00:07:51,500 So format Stringer. Is this just has to have a string method that returns a 120 00:07:51,500 --> 00:07:55,300 string and I have one of those right here. 121 00:07:55,900 --> 00:07:57,800 So let's just check same thing. 122 00:08:01,000 --> 00:08:05,600 Yep, so we know that as a format Stringer, so they can be handy if you want to build 123 00:08:05,600 --> 00:08:09,600 time, verify the something implements particular interface. Now, what 124 00:08:09,600 --> 00:08:13,800 about not implementing something? So, for example, if I go back here, let me 125 00:08:13,800 --> 00:08:15,200 just remove Len again. 126 00:08:17,300 --> 00:08:18,500 And we move the check. 127 00:08:21,500 --> 00:08:25,500 And we'll say, We'll declare within hear that loud string. 128 00:08:25,600 --> 00:08:29,300 Implements that interface. So we've said here go, this is an interface it implements 129 00:08:29,900 --> 00:08:33,800 but Len is missing. So first of all program 130 00:08:33,800 --> 00:08:37,700 builds fine, it doesn't complain. That Len is missing. What happens if I try and 131 00:08:37,700 --> 00:08:39,600 access it? Well, let's try and do that. 132 00:08:43,700 --> 00:08:46,400 So LS, do dot then 133 00:08:49,300 --> 00:08:53,700 Feels fine panics as you not really as a prize is trying to call the 134 00:08:53,700 --> 00:08:57,800 method which doesn't exist and this can actually turn out to be 135 00:08:57,800 --> 00:09:01,800 useful. This might seem like a disastrous thing to do, but by going in 136 00:09:01,800 --> 00:09:05,900 here and declaring the loud string, Implement that interface, it 137 00:09:05,900 --> 00:09:09,600 is now a yellow. If you didn't need to call Len, 138 00:09:09,900 --> 00:09:13,900 then it would be okay that it wasn't implemented. Now that might seem very strange but there's a very 139 00:09:13,900 --> 00:09:17,100 good situation in which you might want to do that, which is in a test Suite. 140 00:09:17,400 --> 00:09:21,600 If you wanted to test some subset of this yella 141 00:09:21,600 --> 00:09:25,500 interface within a test Suite without having to implement everything in a concrete 142 00:09:25,500 --> 00:09:29,900 type, then you could do this. You could say in here, you could embed within a type like 143 00:09:29,900 --> 00:09:33,900 the structure. Yes, I'm commit. Yella that can be passed anywhere where a yeller 144 00:09:33,900 --> 00:09:37,600 is acceptable, but if you don't call the things that are implemented, it's 145 00:09:37,600 --> 00:09:41,800 okay you'll be able to do it. I wouldn't recommend doing this in the main 146 00:09:41,800 --> 00:09:45,800 line of the code but this is the sort of useful work around in the test Suite when you want to pass 147 00:09:45,800 --> 00:09:47,200 something around without having to 148 00:09:47,400 --> 00:09:51,800 Mock up a whole load of functions which you may never actually need to use. So I've 149 00:09:51,800 --> 00:09:55,700 declared that loud string is a yellow but I haven't implemented. 150 00:09:55,700 --> 00:09:59,900 One of the methods in the interface, the Len interface nevertheless. I can still use 151 00:09:59,900 --> 00:10:03,500 my little VAR trick just to verify so I'm just say 152 00:10:03,500 --> 00:10:05,400 is this thing? 153 00:10:06,900 --> 00:10:10,900 A yellow just run to that build and yeah sure enough it is. 154 00:10:10,900 --> 00:10:14,900 So, despite the fact that is not implemented, it is a yellow. And therefore can be passed 155 00:10:14,900 --> 00:10:16,700 anywhere that a yellow is needed.