All language subtitles for English_auto_generated_Go_Programming_–_Golang_Course_with_Bonus

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:00,120 --> 00:00:02,360 welcome to this comprehensive go 2 00:00:02,360 --> 00:00:04,920 programming course for beginners 3 00:00:04,920 --> 00:00:06,919 throughout this course you'll learn key 4 00:00:06,919 --> 00:00:09,160 Concepts and techniques to write 5 00:00:09,160 --> 00:00:12,920 performant idiomatic go code you will be 6 00:00:12,920 --> 00:00:15,160 guided by the expertise of Lane Wagner 7 00:00:15,160 --> 00:00:18,240 and Alan lers who combined have over 18 8 00:00:18,240 --> 00:00:20,880 years of coding experience alongside 9 00:00:20,880 --> 00:00:22,760 mastering topics such as variables 10 00:00:22,760 --> 00:00:25,240 function loops and more you'll also have 11 00:00:25,240 --> 00:00:27,519 the opportunity to apply your new found 12 00:00:27,519 --> 00:00:30,400 skills in seven real world projects 13 00:00:30,400 --> 00:00:32,920 ranging from building an RSS aggregator 14 00:00:32,920 --> 00:00:35,480 to implementing authentication with API 15 00:00:35,480 --> 00:00:38,079 keys so get ready to unlock the 16 00:00:38,079 --> 00:00:41,520 incredible potential of go go has been 17 00:00:41,520 --> 00:00:43,719 exploding in popularity recently it 18 00:00:43,719 --> 00:00:45,200 feels like all the most modern tech 19 00:00:45,200 --> 00:00:47,760 companies are using go to build scalable 20 00:00:47,760 --> 00:00:50,039 backend infrastructure it actually makes 21 00:00:50,039 --> 00:00:52,680 a lot of sense Go's fast lightweight has 22 00:00:52,680 --> 00:00:54,800 an amazing developer experience and is 23 00:00:54,800 --> 00:00:56,760 actually super easy to learn stick 24 00:00:56,760 --> 00:00:58,480 around and in just a few minutes I'll 25 00:00:58,480 --> 00:01:00,680 explain the rest of the reasons why go 26 00:01:00,680 --> 00:01:03,000 could be a game changer for your coding 27 00:01:03,000 --> 00:01:05,119 career at this point I'll just introduce 28 00:01:05,119 --> 00:01:06,920 myself really quickly I'm Lane the 29 00:01:06,920 --> 00:01:08,720 founder of boot. Dev and I've been 30 00:01:08,720 --> 00:01:11,520 writing go for a little over 7 years and 31 00:01:11,520 --> 00:01:13,680 I've been building software for about 10 32 00:01:13,680 --> 00:01:16,360 I've actually spent over 2 years 33 00:01:16,360 --> 00:01:18,600 designing this go course and I've taught 34 00:01:18,600 --> 00:01:21,000 thousands of students with this material 35 00:01:21,000 --> 00:01:22,799 the feedback from all of my students 36 00:01:22,799 --> 00:01:24,000 over the last couple years is actually 37 00:01:24,000 --> 00:01:26,040 been Incorporated in the course so 38 00:01:26,040 --> 00:01:28,200 everything is very battle tested and up 39 00:01:28,200 --> 00:01:30,280 todate I was actually just making some 40 00:01:30,280 --> 00:01:32,000 updates yesterday so how does this 41 00:01:32,000 --> 00:01:34,159 course actually work well we're going to 42 00:01:34,159 --> 00:01:38,520 start by doing over 100 handson coding 43 00:01:38,520 --> 00:01:41,320 lessons and exercises now when we're 44 00:01:41,320 --> 00:01:42,799 done with all of that you'll actually 45 00:01:42,799 --> 00:01:44,320 have a really strong grasp on the 46 00:01:44,320 --> 00:01:46,759 fundamentals so at that point we'll go 47 00:01:46,759 --> 00:01:48,719 build a production ready back-end server 48 00:01:48,719 --> 00:01:52,479 Ino from scratch now I'm begging you 49 00:01:52,479 --> 00:01:55,200 please do not binge watch this video 50 00:01:55,200 --> 00:01:57,600 tutorial hell is a very real place and 51 00:01:57,600 --> 00:02:00,200 it's a place that you will go if you 52 00:02:00,200 --> 00:02:03,360 don't write your own code get your hands 53 00:02:03,360 --> 00:02:05,719 on the keyboard and write some code with 54 00:02:05,719 --> 00:02:08,039 me in fact you should actually be coding 55 00:02:08,039 --> 00:02:10,319 ahead of me and only using my Solutions 56 00:02:10,319 --> 00:02:13,520 when you get stuck so head over to boot. 57 00:02:13,520 --> 00:02:15,080 and create a free account that's where 58 00:02:15,080 --> 00:02:17,440 all of the code samples for this course 59 00:02:17,440 --> 00:02:19,840 are hosted now alternatively I have 60 00:02:19,840 --> 00:02:21,840 linked a GitHub repo in the description 61 00:02:21,840 --> 00:02:24,319 below all of the raw code for the 62 00:02:24,319 --> 00:02:26,519 samples in this course are hosted there 63 00:02:26,519 --> 00:02:27,879 it won't be quite a streamline of an 64 00:02:27,879 --> 00:02:29,440 option but it is an option now you 65 00:02:29,440 --> 00:02:31,319 should also know that this course is 66 00:02:31,319 --> 00:02:33,879 just one part of the full back-end 67 00:02:33,879 --> 00:02:37,319 developer career path over on boot. so 68 00:02:37,319 --> 00:02:38,560 if you're interested in going from zero 69 00:02:38,560 --> 00:02:40,360 to hired as a backend developer you 70 00:02:40,360 --> 00:02:42,840 should definitely check that out too now 71 00:02:42,840 --> 00:02:44,319 as long as we're talking about external 72 00:02:44,319 --> 00:02:46,560 resources know that if you get stuck 73 00:02:46,560 --> 00:02:48,599 during this course you have some options 74 00:02:48,599 --> 00:02:50,640 for help first you've got the boot. deev 75 00:02:50,640 --> 00:02:52,560 Discord second you've got the free code 76 00:02:52,560 --> 00:02:54,120 Camp Discord and third you've got the 77 00:02:54,120 --> 00:02:56,680 free code Camp Forum I will link all of 78 00:02:56,680 --> 00:02:58,640 those down in the description below okay 79 00:02:58,640 --> 00:03:00,400 one last thing before we jump into the 80 00:03:00,400 --> 00:03:02,000 course if you want to connect with me 81 00:03:02,000 --> 00:03:03,560 personally or you want access to my 82 00:03:03,560 --> 00:03:06,200 other go and backend content then you 83 00:03:06,200 --> 00:03:08,920 can follow me on Twitter wag lane or you 84 00:03:08,920 --> 00:03:11,000 can subscribe to my YouTube channel at 85 00:03:11,000 --> 00:03:12,879 boot. I'll link both of those down in 86 00:03:12,879 --> 00:03:14,879 the description below with all of that 87 00:03:14,879 --> 00:03:17,080 out of the way let's talk about go 88 00:03:17,080 --> 00:03:18,760 everyone always wants to talk about how 89 00:03:18,760 --> 00:03:20,920 fast the go programming language is 90 00:03:20,920 --> 00:03:23,080 let's talk about it and let's compare go 91 00:03:23,080 --> 00:03:24,879 to some of the other more popular 92 00:03:24,879 --> 00:03:27,879 programming languages so in terms of 93 00:03:27,879 --> 00:03:31,640 execution speed 94 00:03:32,680 --> 00:03:34,760 execution 95 00:03:34,760 --> 00:03:38,000 speed go is much faster than JavaScript 96 00:03:38,000 --> 00:03:41,319 python Ruby and PHP pretty much any 97 00:03:41,319 --> 00:03:43,280 interpreted language a language that's 98 00:03:43,280 --> 00:03:45,599 not compiled is going to be slower than 99 00:03:45,599 --> 00:03:47,680 go because go is a compiled language now 100 00:03:47,680 --> 00:03:48,840 don't worry too much if you're not 101 00:03:48,840 --> 00:03:50,519 familiar with the terms compiled and 102 00:03:50,519 --> 00:03:52,560 interpreted we'll talk about those in 103 00:03:52,560 --> 00:03:54,319 just a minute for now just understand 104 00:03:54,319 --> 00:03:57,439 that go is much faster um than these 105 00:03:57,439 --> 00:03:59,000 languages when it comes to executing 106 00:03:59,000 --> 00:04:01,000 programs if we're doing computationally 107 00:04:01,000 --> 00:04:03,720 heavy work go is going to be much more 108 00:04:03,720 --> 00:04:05,439 performant um than some of these other 109 00:04:05,439 --> 00:04:08,000 languages now here on the other side 110 00:04:08,000 --> 00:04:10,640 I've listed some compiled languages so 111 00:04:10,640 --> 00:04:14,239 when it comes to compilation 112 00:04:14,239 --> 00:04:16,840 speed compilation 113 00:04:16,840 --> 00:04:19,639 speed go is actually much faster than 114 00:04:19,639 --> 00:04:21,519 these compiled languages when it comes 115 00:04:21,519 --> 00:04:23,919 to compiling the code now again we'll 116 00:04:23,919 --> 00:04:26,000 talk about compiling in a minute but for 117 00:04:26,000 --> 00:04:27,720 now just understand that you have to 118 00:04:27,720 --> 00:04:30,039 compile your code before you can can run 119 00:04:30,039 --> 00:04:31,520 it when you're working with a compiled 120 00:04:31,520 --> 00:04:33,919 language and so by having a fast 121 00:04:33,919 --> 00:04:36,280 compilation speed like go has it 122 00:04:36,280 --> 00:04:37,320 actually increases developer 123 00:04:37,320 --> 00:04:39,840 productivity quite a bit we can iterate 124 00:04:39,840 --> 00:04:41,720 more quickly on our code we can deploy 125 00:04:41,720 --> 00:04:43,919 it more quickly it's not as expensive to 126 00:04:43,919 --> 00:04:47,080 run tests to compile uh the program and 127 00:04:47,080 --> 00:04:48,919 deploy it to production um so this is 128 00:04:48,919 --> 00:04:51,199 actually a huge benefit that go has now 129 00:04:51,199 --> 00:04:52,720 I do want to point out that go does not 130 00:04:52,720 --> 00:04:54,639 necessarily run faster it does not 131 00:04:54,639 --> 00:04:56,759 necessarily have a faster execution 132 00:04:56,759 --> 00:04:59,000 speed than all of these languages but it 133 00:04:59,000 --> 00:05:01,600 does beat them handily when it comes to 134 00:05:01,600 --> 00:05:03,919 compiling not to beat a dead horse but I 135 00:05:03,919 --> 00:05:05,400 want to talk a little bit more about 136 00:05:05,400 --> 00:05:07,759 execution speed so we talked about how 137 00:05:07,759 --> 00:05:09,919 go is generally faster than the 138 00:05:09,919 --> 00:05:11,639 interpreted languages right python 139 00:05:11,639 --> 00:05:14,680 JavaScript Ruby PHP and so on it gets a 140 00:05:14,680 --> 00:05:17,160 little interesting when we compare go to 141 00:05:17,160 --> 00:05:19,199 kind of the natively compiled languages 142 00:05:19,199 --> 00:05:21,759 or the languages that compile directly 143 00:05:21,759 --> 00:05:24,319 to uh kind of machine code that runs on 144 00:05:24,319 --> 00:05:27,319 your CPU versus the compiled languages 145 00:05:27,319 --> 00:05:29,360 that run on top of a virtual machine 146 00:05:29,360 --> 00:05:31,120 right so the the two big ones that run 147 00:05:31,120 --> 00:05:33,440 on a virtual machine are Java and C 148 00:05:33,440 --> 00:05:35,639 while some of the compiled or natively 149 00:05:35,639 --> 00:05:36,759 compiled languages that you'll be 150 00:05:36,759 --> 00:05:40,199 familiar with might be rust C C++ even 151 00:05:40,199 --> 00:05:42,840 though go is a natively compiled 152 00:05:42,840 --> 00:05:44,759 language a language that compiles 153 00:05:44,759 --> 00:05:46,919 directly to machine code like rust C and 154 00:05:46,919 --> 00:05:50,039 C++ its execution speed is actually more 155 00:05:50,039 --> 00:05:54,039 similar to Java and C when it comes to 156 00:05:54,039 --> 00:05:56,479 its runtime speed how many computations 157 00:05:56,479 --> 00:05:58,840 it can do kind of per second and we'll 158 00:05:58,840 --> 00:06:00,600 talk more about this later but the 159 00:06:00,600 --> 00:06:04,720 primary reason for that is the go run 160 00:06:04,720 --> 00:06:07,599 time there's basically a chunk of code 161 00:06:07,599 --> 00:06:10,759 that's included in every go program that 162 00:06:10,759 --> 00:06:13,880 manages memory and that tends to slow 163 00:06:13,880 --> 00:06:15,840 down the execution speed a little bit 164 00:06:15,840 --> 00:06:18,599 that said it is worth pointing out that 165 00:06:18,599 --> 00:06:21,240 a go program tends to use much less 166 00:06:21,240 --> 00:06:24,599 memory than Java and csharp because 167 00:06:24,599 --> 00:06:26,720 there isn't a need for an entire virtual 168 00:06:26,720 --> 00:06:28,800 machine here we are the first coding 169 00:06:28,800 --> 00:06:30,840 challenge let me break down what we are 170 00:06:30,840 --> 00:06:32,120 supposed to do and then I'll kind of 171 00:06:32,120 --> 00:06:33,960 explain what this code over on the right 172 00:06:33,960 --> 00:06:37,560 actually does so um our assignment is to 173 00:06:37,560 --> 00:06:41,479 log the string starting textio server to 174 00:06:41,479 --> 00:06:44,520 the console instead of hello world so 175 00:06:44,520 --> 00:06:46,479 throughout this course we'll be building 176 00:06:46,479 --> 00:06:50,199 out little pieces of the textio product 177 00:06:50,199 --> 00:06:51,960 which if you're familiar with twilio 178 00:06:51,960 --> 00:06:53,680 it'll kind of be like a twilio clone 179 00:06:53,680 --> 00:06:56,599 it's a kind of backend server that sends 180 00:06:56,599 --> 00:06:58,840 SMS and email messages and works a lot 181 00:06:58,840 --> 00:07:01,919 with kind of text textual data every 182 00:07:01,919 --> 00:07:03,720 file of go code has a package 183 00:07:03,720 --> 00:07:05,960 declaration at the top here we have 184 00:07:05,960 --> 00:07:08,919 package main simply because this program 185 00:07:08,919 --> 00:07:11,639 builds into an executable go program 186 00:07:11,639 --> 00:07:13,960 right so we can run this code kind of 187 00:07:13,960 --> 00:07:16,759 Standalone the next line is importing 188 00:07:16,759 --> 00:07:18,800 the fmt package from the standard 189 00:07:18,800 --> 00:07:20,759 Library we are importing it because 190 00:07:20,759 --> 00:07:22,919 we're using it down here within the main 191 00:07:22,919 --> 00:07:25,400 function now the main function is the 192 00:07:25,400 --> 00:07:27,879 entry point to the program so every go 193 00:07:27,879 --> 00:07:31,000 program starts exec ution at the top of 194 00:07:31,000 --> 00:07:32,160 the main function which is just a 195 00:07:32,160 --> 00:07:34,759 function named main that takes no inputs 196 00:07:34,759 --> 00:07:36,960 and doesn't return anything on line six 197 00:07:36,960 --> 00:07:38,840 and seven we have some single line 198 00:07:38,840 --> 00:07:41,039 comments these don't execute they are 199 00:07:41,039 --> 00:07:42,840 not part of the program they're just 200 00:07:42,840 --> 00:07:44,759 there for documentation and single line 201 00:07:44,759 --> 00:07:46,240 comments just start with that double 202 00:07:46,240 --> 00:07:48,720 slack finally on line eight we have the 203 00:07:48,720 --> 00:07:50,280 one thing that this program actually 204 00:07:50,280 --> 00:07:52,720 does which is print the string hello 205 00:07:52,720 --> 00:07:54,360 world to the console so let me go ahead 206 00:07:54,360 --> 00:07:55,440 and run 207 00:07:55,440 --> 00:07:57,720 that see down here it printed to the 208 00:07:57,720 --> 00:08:00,319 console it's using the stand libraries 209 00:08:00,319 --> 00:08:04,039 fmt package um and the print line 210 00:08:04,039 --> 00:08:05,599 function that is exposed from that 211 00:08:05,599 --> 00:08:08,120 package uh to do so so the assignment 212 00:08:08,120 --> 00:08:10,000 here is pretty simple uh we're just 213 00:08:10,000 --> 00:08:12,479 supposed to swap out that hello world 214 00:08:12,479 --> 00:08:15,599 message for starting Tex iio server 215 00:08:15,599 --> 00:08:17,000 going to run that and make sure it looks 216 00:08:17,000 --> 00:08:18,840 like what I would 217 00:08:18,840 --> 00:08:22,000 expect we're good to go next let's fix a 218 00:08:22,000 --> 00:08:25,680 quick bug I love quick wins um we're not 219 00:08:25,680 --> 00:08:27,560 going to talk about all of this syntax 220 00:08:27,560 --> 00:08:29,879 in this program what we're interested in 221 00:08:29,879 --> 00:08:33,760 is just fixing the math bug on line 17 222 00:08:33,760 --> 00:08:35,839 so the assignment description says texo 223 00:08:35,839 --> 00:08:37,279 users are reporting that we're billing 224 00:08:37,279 --> 00:08:39,279 them for wildly inaccurate amounts 225 00:08:39,279 --> 00:08:41,159 they're supposed to be build 226 00:08:41,159 --> 00:08:45,000 for2 for each text message they 227 00:08:45,000 --> 00:08:47,760 send something else is happening so the 228 00:08:47,760 --> 00:08:51,560 total cost here is being set to the cost 229 00:08:51,560 --> 00:08:55,200 per message plus the number of messages 230 00:08:55,200 --> 00:08:56,440 now that doesn't make a lot of sense to 231 00:08:56,440 --> 00:08:58,440 me go ahead and pause the video see if 232 00:08:58,440 --> 00:09:01,440 you can figure this one out on your own 233 00:09:01,440 --> 00:09:03,600 um to me it looks like the cost per 234 00:09:03,600 --> 00:09:05,240 message should be multiplied by the 235 00:09:05,240 --> 00:09:08,640 number of messages right and let me let 236 00:09:08,640 --> 00:09:12,560 me run it like this so that we can see 237 00:09:12,560 --> 00:09:16,760 Doris spent 4.02 on text messages 238 00:09:16,760 --> 00:09:19,120 today four 239 00:09:19,120 --> 00:09:21,360 messages that doesn't make sense right 240 00:09:21,360 --> 00:09:22,920 for four messages she should not be 241 00:09:22,920 --> 00:09:26,680 build $42 if each message only cost 2 242 00:09:26,680 --> 00:09:28,600 cents so I'm going to go ahead and 243 00:09:28,600 --> 00:09:31,920 change that to multiply I would expect 8 244 00:09:31,920 --> 00:09:35,440 cents yep Dora spent 8 cents on text 245 00:09:35,440 --> 00:09:37,000 messages today cool going to go ahead 246 00:09:37,000 --> 00:09:39,640 and submit that this is one of my 247 00:09:39,640 --> 00:09:42,200 favorite XKCD Comics uh you can pause 248 00:09:42,200 --> 00:09:43,640 and read it uh really quick if you'd 249 00:09:43,640 --> 00:09:46,959 like slow and resource expensive 250 00:09:46,959 --> 00:09:49,360 compilation times a really terrible 251 00:09:49,360 --> 00:09:50,920 thing to work with I've worked on 252 00:09:50,920 --> 00:09:53,959 systems in Java and C++ that took over 253 00:09:53,959 --> 00:09:56,200 an hour to compile the code that means 254 00:09:56,200 --> 00:09:58,120 that if we find a bug and we want to 255 00:09:58,120 --> 00:10:00,079 deploy it to production even if we get 256 00:10:00,079 --> 00:10:02,160 the bug fixed within five minutes it's 257 00:10:02,160 --> 00:10:03,959 still going to take an hour just to 258 00:10:03,959 --> 00:10:06,040 build the new production version so that 259 00:10:06,040 --> 00:10:08,240 we can deploy it on our servers I've 260 00:10:08,240 --> 00:10:10,320 personally never worked on a go program 261 00:10:10,320 --> 00:10:11,959 that's taken more than just a couple of 262 00:10:11,959 --> 00:10:14,200 seconds to build and compile so the 263 00:10:14,200 --> 00:10:17,040 first question is go code generally runs 264 00:10:17,040 --> 00:10:19,200 blank than interpreted languages and 265 00:10:19,200 --> 00:10:21,440 compiles blank than other compiled 266 00:10:21,440 --> 00:10:24,240 languages like C and rust so the answer 267 00:10:24,240 --> 00:10:26,320 is going to be faster and faster right 268 00:10:26,320 --> 00:10:27,920 it runs faster than inter most 269 00:10:27,920 --> 00:10:29,760 interpreted languages and it compil Iles 270 00:10:29,760 --> 00:10:31,519 faster than most compiled 271 00:10:31,519 --> 00:10:33,800 languages so the question on this one is 272 00:10:33,800 --> 00:10:36,240 does go generally execute faster than 273 00:10:36,240 --> 00:10:38,720 rust the answer is going to be no so 274 00:10:38,720 --> 00:10:40,920 I've thrown around this word compilation 275 00:10:40,920 --> 00:10:43,200 or compiled a few times but we haven't 276 00:10:43,200 --> 00:10:45,440 really talked about what it means when 277 00:10:45,440 --> 00:10:46,440 we write 278 00:10:46,440 --> 00:10:49,360 code we write it in a human readable 279 00:10:49,360 --> 00:10:52,720 format right typically in a file in the 280 00:10:52,720 --> 00:10:57,120 case of go A.O file right maybe main.go 281 00:10:57,120 --> 00:11:00,000 and this file is going to contain 282 00:11:00,000 --> 00:11:02,720 human readable text right go code that 283 00:11:02,720 --> 00:11:05,279 we as developers work on the thing is 284 00:11:05,279 --> 00:11:08,200 your computer's Hardware doesn't know 285 00:11:08,200 --> 00:11:10,519 what any of that human readable text 286 00:11:10,519 --> 00:11:14,120 means your computer's CPU only 287 00:11:14,120 --> 00:11:15,600 understands 288 00:11:15,600 --> 00:11:19,120 binary right which is ones and 289 00:11:19,120 --> 00:11:21,600 zeros right which at the end of the day 290 00:11:21,600 --> 00:11:23,160 is just numbers right but it's just 291 00:11:23,160 --> 00:11:25,360 numbers and simple operations things 292 00:11:25,360 --> 00:11:29,680 like add and subtract so we need some 293 00:11:29,680 --> 00:11:32,160 process that we can use to convert human 294 00:11:32,160 --> 00:11:35,000 readable code to machine code that can 295 00:11:35,000 --> 00:11:37,160 be executed by the computer's hardware 296 00:11:37,160 --> 00:11:40,560 and that's all that compilation is 297 00:11:40,560 --> 00:11:42,200 compilation is just the process of 298 00:11:42,200 --> 00:11:45,160 taking some human readable code right go 299 00:11:45,160 --> 00:11:47,720 code in our instance and converting it 300 00:11:47,720 --> 00:11:50,320 to Binary or machine code that our 301 00:11:50,320 --> 00:11:52,040 computer can actually understand so what 302 00:11:52,040 --> 00:11:54,959 does this process actually look like 303 00:11:54,959 --> 00:11:57,880 Well normally you'd start by writing 304 00:11:57,880 --> 00:12:02,320 your go program so say main.go 305 00:12:02,320 --> 00:12:05,920 and you'd run it through the go compiler 306 00:12:05,920 --> 00:12:09,800 on your command line you'd type go 307 00:12:11,079 --> 00:12:14,440 build and that would produce a new file 308 00:12:14,440 --> 00:12:16,519 which is the executable program let's 309 00:12:16,519 --> 00:12:18,560 say we're doing a hello word a hello 310 00:12:18,560 --> 00:12:20,839 world program it might be 311 00:12:20,839 --> 00:12:23,839 hello 312 00:12:24,160 --> 00:12:25,720 world.exe 313 00:12:25,720 --> 00:12:28,199 right an executable program on your 314 00:12:28,199 --> 00:12:30,279 computer and you could run that 315 00:12:30,279 --> 00:12:32,519 executable directly on your operating 316 00:12:32,519 --> 00:12:34,760 system without ever having to use the go 317 00:12:34,760 --> 00:12:37,399 tool chain again so the great thing is 318 00:12:37,399 --> 00:12:39,600 you can take this hello world.exe 319 00:12:39,600 --> 00:12:42,160 program and give it to someone else and 320 00:12:42,160 --> 00:12:44,040 they can run it on their computer 321 00:12:44,040 --> 00:12:46,160 without ever having to install the go 322 00:12:46,160 --> 00:12:48,880 tool chain or even know that you used go 323 00:12:48,880 --> 00:12:50,720 to build the program in the first place 324 00:12:50,720 --> 00:12:52,240 this is different than languages like 325 00:12:52,240 --> 00:12:54,279 python where if you want to run 326 00:12:54,279 --> 00:12:56,760 someone's python code you have to use 327 00:12:56,760 --> 00:12:59,279 the python interpreter every single time 328 00:12:59,279 --> 00:13:02,279 time and you run the source code you run 329 00:13:02,279 --> 00:13:04,399 the source code directly on your machine 330 00:13:04,399 --> 00:13:06,440 it's also worth pointing out that part 331 00:13:06,440 --> 00:13:09,199 of the reason that compiling is so much 332 00:13:09,199 --> 00:13:12,040 faster at runtime is that we do all of 333 00:13:12,040 --> 00:13:14,760 this compiling work upfront so when we 334 00:13:14,760 --> 00:13:16,760 go to run the executable we don't have 335 00:13:16,760 --> 00:13:18,760 to do any conversions from Human 336 00:13:18,760 --> 00:13:21,600 readable text to Binary machine code 337 00:13:21,600 --> 00:13:23,519 that's different than how interpreted 338 00:13:23,519 --> 00:13:25,279 languages work with an interpreted 339 00:13:25,279 --> 00:13:28,120 language as we run the program The 340 00:13:28,120 --> 00:13:30,800 Interpreter is reading the human code 341 00:13:30,800 --> 00:13:33,680 and kind of at runtime converting it to 342 00:13:33,680 --> 00:13:36,040 machine code that the CPU can operate on 343 00:13:36,040 --> 00:13:38,680 so you might be wondering where is the 344 00:13:38,680 --> 00:13:41,360 compiling Happening Here on botev well 345 00:13:41,360 --> 00:13:43,320 we actually do the compiling and the 346 00:13:43,320 --> 00:13:45,279 running at the same time for you so when 347 00:13:45,279 --> 00:13:47,079 you click the Run button um we're 348 00:13:47,079 --> 00:13:48,800 actually taking your code shipping it 349 00:13:48,800 --> 00:13:51,519 off to our servers compiling it running 350 00:13:51,519 --> 00:13:54,279 it and giving you the result don't worry 351 00:13:54,279 --> 00:13:56,519 when we get down the road to the actual 352 00:13:56,519 --> 00:13:58,320 project you'll be building and running 353 00:13:58,320 --> 00:14:01,199 your own go code on your own machine but 354 00:14:01,199 --> 00:14:03,320 we can see the difference between a 355 00:14:03,320 --> 00:14:06,040 compiler error and a runtime error even 356 00:14:06,040 --> 00:14:08,720 here on Bev so for example um here in 357 00:14:08,720 --> 00:14:11,320 this code the assignment says to pass 358 00:14:11,320 --> 00:14:13,240 this exercise fix the compiler error in 359 00:14:13,240 --> 00:14:15,519 the code so I'm just going to run it as 360 00:14:15,519 --> 00:14:17,600 is and you'll see we get this nasty 361 00:14:17,600 --> 00:14:20,120 error here and it says main.go right 362 00:14:20,120 --> 00:14:23,079 line six syntax error this is actually a 363 00:14:23,079 --> 00:14:25,440 compile time error so we weren't even 364 00:14:25,440 --> 00:14:28,000 able to compile this code it didn't fail 365 00:14:28,000 --> 00:14:30,519 at runtime it failed compile time right 366 00:14:30,519 --> 00:14:32,000 which again that distinction will become 367 00:14:32,000 --> 00:14:34,560 more clear a little bit later so anyways 368 00:14:34,560 --> 00:14:36,320 um we can fix it by adding that Clos 369 00:14:36,320 --> 00:14:38,839 parentheses that was 370 00:14:38,839 --> 00:14:42,120 missing and now it compiles and runs 371 00:14:42,120 --> 00:14:43,680 just 372 00:14:43,680 --> 00:14:47,959 fine so to review go code like this 373 00:14:47,959 --> 00:14:50,480 little go program here that prints hello 374 00:14:50,480 --> 00:14:53,839 world that's not understood directly by 375 00:14:53,839 --> 00:14:56,360 the hardware on your computer your 376 00:14:56,360 --> 00:14:58,519 computer's processor or your computer's 377 00:14:58,519 --> 00:14:59,839 CPU 378 00:14:59,839 --> 00:15:02,680 understands machine codee so we need to 379 00:15:02,680 --> 00:15:06,120 take our human readable go code run it 380 00:15:06,120 --> 00:15:08,120 through the go compiler to produce the 381 00:15:08,120 --> 00:15:10,800 machine code that we can run directly on 382 00:15:10,800 --> 00:15:13,800 our CPU right the CPU is designed by the 383 00:15:13,800 --> 00:15:18,120 manufacturer to run a specific format of 384 00:15:18,120 --> 00:15:20,480 binary cool so the question for this 385 00:15:20,480 --> 00:15:23,079 exercise is do computer processors 386 00:15:23,079 --> 00:15:25,079 understand English instructions like 387 00:15:25,079 --> 00:15:26,920 open the 388 00:15:26,920 --> 00:15:30,639 browser no processors are not chat GPT 389 00:15:30,639 --> 00:15:32,120 uh they need machine 390 00:15:32,120 --> 00:15:34,920 code now we touched on this very briefly 391 00:15:34,920 --> 00:15:36,839 before but I want to talk about how you 392 00:15:36,839 --> 00:15:39,399 distribute a compiled program versus how 393 00:15:39,399 --> 00:15:40,920 you would distribute an interpreted 394 00:15:40,920 --> 00:15:43,560 program so let's say that you'd written 395 00:15:43,560 --> 00:15:45,519 a script in Python so you've got this 396 00:15:45,519 --> 00:15:49,720 script main.py right this is raw python 397 00:15:49,720 --> 00:15:51,920 code and you want to give it to your 398 00:15:51,920 --> 00:15:54,160 friend so that they can run your script 399 00:15:54,160 --> 00:15:56,040 well all you would do with an 400 00:15:56,040 --> 00:15:59,560 interpreted language is give your friend 401 00:15:59,560 --> 00:16:02,600 the main.py file and then on their 402 00:16:02,600 --> 00:16:06,360 computer they would run the command 403 00:16:06,360 --> 00:16:09,360 Python 404 00:16:09,759 --> 00:16:11,600 main.py and they'd be able to run your 405 00:16:11,600 --> 00:16:14,120 code now there are a couple of downsides 406 00:16:14,120 --> 00:16:16,120 to this approach the first problem is 407 00:16:16,120 --> 00:16:18,839 that your friend needs to have python 408 00:16:18,839 --> 00:16:21,560 installed on their computer so your your 409 00:16:21,560 --> 00:16:24,079 friend being able to use your program is 410 00:16:24,079 --> 00:16:27,160 dependent on them already having python 411 00:16:27,160 --> 00:16:29,160 installed it's even dependent on them 412 00:16:29,160 --> 00:16:30,800 knowing how to use it or knowing how to 413 00:16:30,800 --> 00:16:33,199 use a command line right so Distributing 414 00:16:33,199 --> 00:16:35,120 the programs of interpreted languages 415 00:16:35,120 --> 00:16:37,240 can be tricky because it's really only 416 00:16:37,240 --> 00:16:39,000 useful if you're Distributing to other 417 00:16:39,000 --> 00:16:40,560 developers who know how to use these 418 00:16:40,560 --> 00:16:43,160 tools already the other problem is the 419 00:16:43,160 --> 00:16:46,160 code itself let's say you spent you know 420 00:16:46,160 --> 00:16:48,480 many weeks writing this python script 421 00:16:48,480 --> 00:16:50,199 and it's super useful and you're trying 422 00:16:50,199 --> 00:16:53,120 to sell it to customers if you just give 423 00:16:53,120 --> 00:16:55,279 them your python code I mean they 424 00:16:55,279 --> 00:16:57,120 effectively own it they can change it 425 00:16:57,120 --> 00:16:59,399 even if you didn't intend for it be open 426 00:16:59,399 --> 00:17:02,160 source congratulations it's now open 427 00:17:02,160 --> 00:17:04,880 source the problem is you can't really 428 00:17:04,880 --> 00:17:07,439 allow someone to use your program 429 00:17:07,439 --> 00:17:10,600 without giving them all of the Special 430 00:17:10,600 --> 00:17:12,959 Sauce that makes it work let's review 431 00:17:12,959 --> 00:17:16,240 how this works in a language like go so 432 00:17:16,240 --> 00:17:18,520 in go we'd start the same way right we'd 433 00:17:18,520 --> 00:17:20,600 write some human readable go code in a 434 00:17:20,600 --> 00:17:22,880 file called main.go but instead of 435 00:17:22,880 --> 00:17:24,799 giving that file to our friend we're 436 00:17:24,799 --> 00:17:26,959 going to compile it 437 00:17:26,959 --> 00:17:29,559 first going to compile it 438 00:17:29,559 --> 00:17:31,600 we'd use the go go tool chain so we'd 439 00:17:31,600 --> 00:17:33,520 write something like go build in our 440 00:17:33,520 --> 00:17:36,280 command line and that would produce a 441 00:17:36,280 --> 00:17:38,760 new executable file right so this is 442 00:17:38,760 --> 00:17:42,080 this is machine code here um let's just 443 00:17:42,080 --> 00:17:44,960 say that the name of our program is 444 00:17:44,960 --> 00:17:47,039 Hello World why 445 00:17:47,039 --> 00:17:49,360 not so if we're on Windows it might be 446 00:17:49,360 --> 00:17:51,640 hello world.exe 447 00:17:51,640 --> 00:17:54,360 right so when you go online and you 448 00:17:54,360 --> 00:17:56,600 download a program to use say it's a 449 00:17:56,600 --> 00:17:59,600 video game um it is probably 450 00:17:59,600 --> 00:18:01,760 a bundle of machine code it is a built 451 00:18:01,760 --> 00:18:04,320 binary right in order to run your 452 00:18:04,320 --> 00:18:06,240 favorite video game let's say Starcraft 453 00:18:06,240 --> 00:18:08,600 2 or World of Warcraft you don't need to 454 00:18:08,600 --> 00:18:12,120 install the C++ compiler right you're 455 00:18:12,120 --> 00:18:14,600 just given the built kind of final 456 00:18:14,600 --> 00:18:18,200 product the final executable program and 457 00:18:18,200 --> 00:18:20,880 that's what we're doing in uh the go 458 00:18:20,880 --> 00:18:22,679 programming language as well so now we 459 00:18:22,679 --> 00:18:24,320 can give our friend this 460 00:18:24,320 --> 00:18:26,960 executable they don't need to install go 461 00:18:26,960 --> 00:18:28,960 and they do not need access to the 462 00:18:28,960 --> 00:18:31,240 original source code so generally 463 00:18:31,240 --> 00:18:33,640 speaking Distributing programs that are 464 00:18:33,640 --> 00:18:36,559 natively compiled is much much easier um 465 00:18:36,559 --> 00:18:38,600 than Distributing programs that kind of 466 00:18:38,600 --> 00:18:40,880 have a runtime dependency like an 467 00:18:40,880 --> 00:18:43,200 interpreter so to answer the question 468 00:18:43,200 --> 00:18:46,159 for this exercise do users of compiled 469 00:18:46,159 --> 00:18:49,039 programs need access to the source code 470 00:18:49,039 --> 00:18:51,840 no they don't and a related question 471 00:18:51,840 --> 00:18:53,919 which language is interpreted we've got 472 00:18:53,919 --> 00:19:00,360 go C++ Python and rust and the answer is 473 00:19:00,360 --> 00:19:03,400 python the rest are all compiled so now 474 00:19:03,400 --> 00:19:05,480 the question is why is it generally more 475 00:19:05,480 --> 00:19:08,640 simple to deploy a compiled serers side 476 00:19:08,640 --> 00:19:10,679 program or backend application and the 477 00:19:10,679 --> 00:19:12,640 answers are compiled code is more memory 478 00:19:12,640 --> 00:19:14,960 efficient because Docker exists there 479 00:19:14,960 --> 00:19:17,919 are no runtime language dependencies or 480 00:19:17,919 --> 00:19:20,039 because compiled code is 481 00:19:20,039 --> 00:19:22,360 faster well it's just the same as what 482 00:19:22,360 --> 00:19:24,919 we talked about earlier um when we 483 00:19:24,919 --> 00:19:27,840 deploy to a server say on the cloud uh 484 00:19:27,840 --> 00:19:30,320 we have to have all of the dependencies 485 00:19:30,320 --> 00:19:33,280 uh that our backend application needs in 486 00:19:33,280 --> 00:19:36,320 order to run installed on that server 487 00:19:36,320 --> 00:19:38,840 and if there are no runtime dependencies 488 00:19:38,840 --> 00:19:42,360 if all we need is a compiled binary then 489 00:19:42,360 --> 00:19:44,120 that's arguably the simplest way to do 490 00:19:44,120 --> 00:19:46,919 it right so the answer is it's more 491 00:19:46,919 --> 00:19:48,840 simple to deploy a comp to deploy a 492 00:19:48,840 --> 00:19:51,919 compiled program to a back-end server if 493 00:19:51,919 --> 00:19:54,000 there are no runtime language 494 00:19:54,000 --> 00:19:55,960 dependencies things like the python 495 00:19:55,960 --> 00:19:58,720 interpreter or The nodejs Interpreter 496 00:19:58,720 --> 00:20:02,360 for example go is strongly typed and 497 00:20:02,360 --> 00:20:05,039 statically typed and that's a really 498 00:20:05,039 --> 00:20:06,799 good thing if you've been paying any 499 00:20:06,799 --> 00:20:09,120 attention at all to the JavaScript World 500 00:20:09,120 --> 00:20:10,799 you'll notice that a lot of JavaScript 501 00:20:10,799 --> 00:20:12,880 developers are making the switch to 502 00:20:12,880 --> 00:20:15,919 typescript and that's primarily to get 503 00:20:15,919 --> 00:20:19,720 access to static typing a lot goes into 504 00:20:19,720 --> 00:20:22,440 typing and type systems but one of the 505 00:20:22,440 --> 00:20:25,240 biggest benefits of a static type system 506 00:20:25,240 --> 00:20:27,799 like goes is that when we declare a 507 00:20:27,799 --> 00:20:30,400 string right like say this username 508 00:20:30,400 --> 00:20:33,400 string that I've set equal to wag Lane 509 00:20:33,400 --> 00:20:36,400 we can't later accidentally change it to 510 00:20:36,400 --> 00:20:38,480 an integer a number right like a float 511 00:20:38,480 --> 00:20:42,200 64 um it's going to stay a string the 512 00:20:42,200 --> 00:20:44,280 nice thing about a static type system 513 00:20:44,280 --> 00:20:45,799 like we have with go or that you have 514 00:20:45,799 --> 00:20:47,640 with typescript is that we get feedback 515 00:20:47,640 --> 00:20:50,440 on our errors uh much more quickly right 516 00:20:50,440 --> 00:20:52,320 rather than finding out about a bug when 517 00:20:52,320 --> 00:20:53,960 our code is running in production we 518 00:20:53,960 --> 00:20:55,720 find out about the bug say when we 519 00:20:55,720 --> 00:20:57,520 compile our code let's move on to the 520 00:20:57,520 --> 00:20:59,280 assignment the the assignment says we'll 521 00:20:59,280 --> 00:21:01,120 be using basic authentication for the 522 00:21:01,120 --> 00:21:03,960 text iio API so basic authentication is 523 00:21:03,960 --> 00:21:05,520 is just this format here where you've 524 00:21:05,520 --> 00:21:08,280 got a username and a password um in an 525 00:21:08,280 --> 00:21:11,960 HTTP header it tells the server on each 526 00:21:11,960 --> 00:21:14,320 individual request to the server who you 527 00:21:14,320 --> 00:21:17,080 are right it's kind of like logging in 528 00:21:17,080 --> 00:21:19,400 um or rather it's kind of like being 529 00:21:19,400 --> 00:21:24,159 logged in okay uh so the code on the 530 00:21:24,159 --> 00:21:26,279 right has a type error change the type 531 00:21:26,279 --> 00:21:27,919 of password to a string Okay cool so I'm 532 00:21:27,919 --> 00:21:29,159 just going to run it to see the type 533 00:21:29,159 --> 00:21:31,159 error first so invalid operation 534 00:21:31,159 --> 00:21:33,960 username plus colon plus password has 535 00:21:33,960 --> 00:21:36,039 mismatch types of string and int now 536 00:21:36,039 --> 00:21:37,799 this is a compile time error we we 537 00:21:37,799 --> 00:21:39,440 weren't even able to compile this code 538 00:21:39,440 --> 00:21:42,520 right let alone run it in production um 539 00:21:42,520 --> 00:21:44,159 so we've been instructed in the 540 00:21:44,159 --> 00:21:46,000 assignment change the type of password 541 00:21:46,000 --> 00:21:48,080 to a string but use the same numeric 542 00:21:48,080 --> 00:21:50,080 value so that it can be concatenated 543 00:21:50,080 --> 00:21:52,360 with the username variable Okay cool so 544 00:21:52,360 --> 00:21:53,720 I'm just going to change this to a 545 00:21:53,720 --> 00:21:56,559 string by surrounding in double quotes 546 00:21:56,559 --> 00:21:59,159 that's how you do strings and go 547 00:21:59,159 --> 00:22:00,440 pretty similar to other languages and 548 00:22:00,440 --> 00:22:02,799 then I'm just going to change that type 549 00:22:02,799 --> 00:22:06,240 to a string type and run it again 550 00:22:06,240 --> 00:22:09,679 authorization basic wag Lane colon 551 00:22:09,679 --> 00:22:12,720 number that looks good to 552 00:22:12,720 --> 00:22:14,760 me when we're talking about the 553 00:22:14,760 --> 00:22:16,760 performance of a programming language or 554 00:22:16,760 --> 00:22:19,320 an application we really care about how 555 00:22:19,320 --> 00:22:21,520 it performs across two different axes 556 00:22:21,520 --> 00:22:24,240 one is speed how fast it can do 557 00:22:24,240 --> 00:22:26,080 computations right which is kind of 558 00:22:26,080 --> 00:22:28,880 measured in CPU cycles and then we also 559 00:22:28,880 --> 00:22:31,559 have memory consumption which is just 560 00:22:31,559 --> 00:22:34,000 how bloaty the program is how much data 561 00:22:34,000 --> 00:22:36,679 it has to store in memory to be able to 562 00:22:36,679 --> 00:22:38,840 do those computations every program you 563 00:22:38,840 --> 00:22:41,159 write no matter the language is going to 564 00:22:41,159 --> 00:22:44,080 be using memory every time you create a 565 00:22:44,080 --> 00:22:46,120 new variable it allocates space in 566 00:22:46,120 --> 00:22:48,159 memory where it can store that 567 00:22:48,159 --> 00:22:51,039 variable's data now in languages like 568 00:22:51,039 --> 00:22:53,919 rust or C memory management is 569 00:22:53,919 --> 00:22:56,919 effectively manual now that said Russ 570 00:22:56,919 --> 00:22:59,320 does have some nice tooling that kind of 571 00:22:59,320 --> 00:23:01,080 takes care of it for you at compile time 572 00:23:01,080 --> 00:23:03,640 so it's not quite as error prone um as 573 00:23:03,640 --> 00:23:06,039 as it would be in C or C++ but at the 574 00:23:06,039 --> 00:23:08,000 end of the day your program is 575 00:23:08,000 --> 00:23:10,520 allocating memory right it's saying this 576 00:23:10,520 --> 00:23:12,559 chunk of memory I'm going to use I'm 577 00:23:12,559 --> 00:23:14,679 going to store some variable data here 578 00:23:14,679 --> 00:23:17,279 in this bit of RAM and then later your 579 00:23:17,279 --> 00:23:20,279 program says I'm not using it anymore um 580 00:23:20,279 --> 00:23:22,279 so we can free it up for use by other 581 00:23:22,279 --> 00:23:25,159 programs now let's jump over to Java so 582 00:23:25,159 --> 00:23:27,279 with Java it's a little bit different um 583 00:23:27,279 --> 00:23:29,240 Java is a garbage CL CED language 584 00:23:29,240 --> 00:23:31,200 garbage collection which essentially 585 00:23:31,200 --> 00:23:35,200 means that memory management is 586 00:23:35,200 --> 00:23:37,919 automated and in Java it's done by the 587 00:23:37,919 --> 00:23:40,320 Java virtual machine so every time you 588 00:23:40,320 --> 00:23:42,960 run a Java program you're actually 589 00:23:42,960 --> 00:23:44,400 creating an 590 00:23:44,400 --> 00:23:47,960 entire mini virtual 591 00:23:47,960 --> 00:23:51,400 machine that your Java bite code runs 592 00:23:51,400 --> 00:23:54,840 within so this is the 593 00:23:54,840 --> 00:23:57,520 jvm and then you kind of insert your 594 00:23:57,520 --> 00:23:59,480 code 595 00:23:59,480 --> 00:24:01,440 into the 596 00:24:01,440 --> 00:24:06,080 jvm and you run your code in there and 597 00:24:06,080 --> 00:24:08,919 the jvm is what takes care of allocating 598 00:24:08,919 --> 00:24:11,039 and freeing all of the memory that you 599 00:24:11,039 --> 00:24:14,559 use and this creates overhead basically 600 00:24:14,559 --> 00:24:17,520 at the end of the day Java programs use 601 00:24:17,520 --> 00:24:20,279 quite a bit more memory than rust or C 602 00:24:20,279 --> 00:24:23,480 programs go is in an interesting sort of 603 00:24:23,480 --> 00:24:26,120 in between world where go is a garbage 604 00:24:26,120 --> 00:24:29,600 collected language like Java so it has 605 00:24:29,600 --> 00:24:32,360 automated automated memory management 606 00:24:32,360 --> 00:24:34,960 but it does not have a jvm when you 607 00:24:34,960 --> 00:24:38,000 compile go code rather than having to 608 00:24:38,000 --> 00:24:41,000 run it within a jvm just like with Rus 609 00:24:41,000 --> 00:24:45,120 and C you get one binary or one 610 00:24:45,120 --> 00:24:47,640 executable program the difference is 611 00:24:47,640 --> 00:24:51,240 that go includes a 612 00:24:51,240 --> 00:24:53,600 runtime a 613 00:24:53,600 --> 00:24:57,440 runtime within every single binary 614 00:24:57,440 --> 00:24:59,399 that's built using the go programming 615 00:24:59,399 --> 00:25:02,120 language so we could think of it as 616 00:25:02,120 --> 00:25:03,279 something like this it's kind of like a 617 00:25:03,279 --> 00:25:04,960 little side 618 00:25:04,960 --> 00:25:07,720 car that is compiled 619 00:25:07,720 --> 00:25:12,120 alongside your code so your go program 620 00:25:12,120 --> 00:25:14,360 basically has this this little bit of 621 00:25:14,360 --> 00:25:17,360 extra code that's added to it and that 622 00:25:17,360 --> 00:25:19,679 bit of code is what handles garbage 623 00:25:19,679 --> 00:25:21,440 collection and automated memory 624 00:25:21,440 --> 00:25:23,840 management so it's a little more bloaty 625 00:25:23,840 --> 00:25:25,919 than what you'd get with rust and C 626 00:25:25,919 --> 00:25:28,720 right it is garbage collected um but 627 00:25:28,720 --> 00:25:32,240 it's not nearly as um expensive in terms 628 00:25:32,240 --> 00:25:34,679 of memory overhead as a language like 629 00:25:34,679 --> 00:25:37,600 Java or C let's take a look at what some 630 00:25:37,600 --> 00:25:39,919 actual numbers look like I pulled this 631 00:25:39,919 --> 00:25:42,600 chart from Dexter darwick uh blog and if 632 00:25:42,600 --> 00:25:43,880 you're following Along on botev you can 633 00:25:43,880 --> 00:25:45,880 click the link to go check out the full 634 00:25:45,880 --> 00:25:47,279 the full blog and the description of 635 00:25:47,279 --> 00:25:50,120 this experiment but basically he built a 636 00:25:50,120 --> 00:25:52,360 restful web server in three different 637 00:25:52,360 --> 00:25:54,279 programming languages right in Java go 638 00:25:54,279 --> 00:25:56,840 and rust and then me measured the memory 639 00:25:56,840 --> 00:25:58,880 consumption and when the servers were 640 00:25:58,880 --> 00:26:01,080 just at rest effectively doing nothing 641 00:26:01,080 --> 00:26:04,480 and waiting for requests to come in Rust 642 00:26:04,480 --> 00:26:07,559 used less than half of the memory that 643 00:26:07,559 --> 00:26:12,919 go was using and go used 100 times less 644 00:26:12,919 --> 00:26:15,320 memory right measured in megabytes than 645 00:26:15,320 --> 00:26:18,399 the jvm was using to run the rest 646 00:26:18,399 --> 00:26:20,919 service so to order the three languages 647 00:26:20,919 --> 00:26:22,640 in terms of memory efficiency I would 648 00:26:22,640 --> 00:26:25,279 say Java is the least efficient uh go is 649 00:26:25,279 --> 00:26:27,559 in the middle and rust would be the most 650 00:26:27,559 --> 00:26:29,679 memory efficient and it's also worth 651 00:26:29,679 --> 00:26:31,880 pointing out just really quickly that as 652 00:26:31,880 --> 00:26:34,840 the load on the server increases I would 653 00:26:34,840 --> 00:26:38,679 expect go to have more similar 654 00:26:38,679 --> 00:26:40,200 performance to Java in other words we 655 00:26:40,200 --> 00:26:42,320 wouldn't see as quite a large 656 00:26:42,320 --> 00:26:45,360 discrepancy here right go would likely 657 00:26:45,360 --> 00:26:47,960 still be more memory efficient than Java 658 00:26:47,960 --> 00:26:50,080 almost certainly in fact um but it 659 00:26:50,080 --> 00:26:53,240 probably wouldn't be a 100x discrepancy 660 00:26:53,240 --> 00:26:56,279 we're seeing this huge discrepancy um 661 00:26:56,279 --> 00:26:59,360 mostly because this is an idol uh a test 662 00:26:59,360 --> 00:27:02,520 of an idle program so generally speaking 663 00:27:02,520 --> 00:27:04,679 which language uses more memory that's 664 00:27:04,679 --> 00:27:07,440 going to be Java another question on the 665 00:27:07,440 --> 00:27:09,840 same topic is what's one of the purposes 666 00:27:09,840 --> 00:27:13,720 of the go runtime so to style go code 667 00:27:13,720 --> 00:27:15,440 and make it easier to read that doesn't 668 00:27:15,440 --> 00:27:17,200 make sense that would be like compile 669 00:27:17,200 --> 00:27:20,039 time tooling right not run time tooling 670 00:27:20,039 --> 00:27:22,240 to clean up unused memory to cook fried 671 00:27:22,240 --> 00:27:24,480 chicken or to compile go- code so it's 672 00:27:24,480 --> 00:27:26,000 definitely going to be to clean up 673 00:27:26,000 --> 00:27:28,200 unused memory and if you remember 674 00:27:28,200 --> 00:27:30,000 remember the runtime is just that little 675 00:27:30,000 --> 00:27:31,919 bit of extra code that's included in 676 00:27:31,919 --> 00:27:35,320 every compiled go program that among 677 00:27:35,320 --> 00:27:37,559 other things handles memory 678 00:27:37,559 --> 00:27:39,600 management so we've already talked about 679 00:27:39,600 --> 00:27:42,919 how go has strong and static types but 680 00:27:42,919 --> 00:27:44,360 we haven't yet talked about what those 681 00:27:44,360 --> 00:27:46,360 types are you're probably already 682 00:27:46,360 --> 00:27:49,120 familiar with Boolean values and string 683 00:27:49,120 --> 00:27:51,799 values which are valid go types and also 684 00:27:51,799 --> 00:27:53,080 exist in pretty much every other 685 00:27:53,080 --> 00:27:55,120 programming language um numbers are 686 00:27:55,120 --> 00:27:56,559 where it first starts to get a little 687 00:27:56,559 --> 00:27:59,559 bit different uh if go is your first 688 00:27:59,559 --> 00:28:01,919 compiled programming language generally 689 00:28:01,919 --> 00:28:03,600 speaking numbers fall into four 690 00:28:03,600 --> 00:28:06,240 different buckets we have integers 691 00:28:06,240 --> 00:28:10,320 unsigned integers or uints floats and 692 00:28:10,320 --> 00:28:13,279 complex numbers integers are just whole 693 00:28:13,279 --> 00:28:15,240 numbers they can be positive or negative 694 00:28:15,240 --> 00:28:19,000 right 1 2 3 4 you get the idea unsigned 695 00:28:19,000 --> 00:28:21,320 integers are the same as integers but 696 00:28:21,320 --> 00:28:22,640 they're not signed which basically just 697 00:28:22,640 --> 00:28:24,640 means they don't have a negative 698 00:28:24,640 --> 00:28:26,880 component you can only represent 699 00:28:26,880 --> 00:28:28,840 positive numbers in in an unsigned 700 00:28:28,840 --> 00:28:30,640 integer you probably already familiar 701 00:28:30,640 --> 00:28:32,159 with the idea of floats it's just 702 00:28:32,159 --> 00:28:33,919 fractional numbers right numbers that 703 00:28:33,919 --> 00:28:36,480 have a fractional component things like 704 00:28:36,480 --> 00:28:38,559 1.21 or 705 00:28:38,559 --> 00:28:41,000 3.14 complex numbers are a little funny 706 00:28:41,000 --> 00:28:43,679 they're used to represent the concept of 707 00:28:43,679 --> 00:28:46,360 imaginary numbers if you've gotten to 708 00:28:46,360 --> 00:28:49,080 imaginary numbers in your math studies 709 00:28:49,080 --> 00:28:51,559 I've never actually used complex numbers 710 00:28:51,559 --> 00:28:53,679 um in production I'm sure there are 711 00:28:53,679 --> 00:28:55,440 plenty of use cases for them but we're 712 00:28:55,440 --> 00:28:56,840 not going to go into detail on how they 713 00:28:56,840 --> 00:28:58,480 work here you can certainly go read up 714 00:28:58,480 --> 00:29:00,480 on it if you'd like the only other thing 715 00:29:00,480 --> 00:29:02,519 worth mentioning is that size matters 716 00:29:02,519 --> 00:29:05,720 when it comes to types A uint 8 and a 717 00:29:05,720 --> 00:29:08,600 uint 16 are two different types they 718 00:29:08,600 --> 00:29:11,720 both represent unsigned integers but a u 719 00:29:11,720 --> 00:29:15,279 16 has twice as much room for data 720 00:29:15,279 --> 00:29:18,640 within it it has 16 bits of data whereas 721 00:29:18,640 --> 00:29:21,760 a u 8 only has eight bits for example 722 00:29:21,760 --> 00:29:23,679 the largest number that you can store in 723 00:29:23,679 --> 00:29:27,559 a uint 8 is 255 because that's the 724 00:29:27,559 --> 00:29:29,080 largest number you can represent with 725 00:29:29,080 --> 00:29:31,720 eight 1es and zeros in binary but with a 726 00:29:31,720 --> 00:29:34,480 uint 16 the largest number you can store 727 00:29:34,480 --> 00:29:35,760 is about 728 00:29:35,760 --> 00:29:38,080 65,000 again because that's the biggest 729 00:29:38,080 --> 00:29:40,600 number that can be represented by 16 730 00:29:40,600 --> 00:29:43,159 binary digits just like bigger number 731 00:29:43,159 --> 00:29:45,480 better person uh bigger number in your 732 00:29:45,480 --> 00:29:47,559 types means you can represent more 733 00:29:47,559 --> 00:29:50,679 possible values uh within that type so 734 00:29:50,679 --> 00:29:53,519 float 64 can represent more values than 735 00:29:53,519 --> 00:29:56,600 a float 32 the only reason you wouldn't 736 00:29:56,600 --> 00:29:59,080 use a larger type is if you're trying to 737 00:29:59,080 --> 00:30:01,240 save on memory if you're trying to write 738 00:30:01,240 --> 00:30:03,360 a program that is hyper performant 739 00:30:03,360 --> 00:30:06,000 you'll want to use a smaller size right 740 00:30:06,000 --> 00:30:08,120 if you know that an integer is only ever 741 00:30:08,120 --> 00:30:09,799 going to store three different values 742 00:30:09,799 --> 00:30:11,600 say 1 two or three then you might 743 00:30:11,600 --> 00:30:14,399 consider using a u and 8 the bite type 744 00:30:14,399 --> 00:30:15,799 is an interesting one and it's one that 745 00:30:15,799 --> 00:30:17,799 you'll use a lot especially when you're 746 00:30:17,799 --> 00:30:20,519 say marshalling a Json object um to be 747 00:30:20,519 --> 00:30:22,679 sent across a network connection or 748 00:30:22,679 --> 00:30:24,559 maybe you're reading to and from a file 749 00:30:24,559 --> 00:30:27,399 on disk um but under the hood a bite is 750 00:30:27,399 --> 00:30:30,279 just an Alias for the uint8 type which 751 00:30:30,279 --> 00:30:32,600 makes sense right a bite is just eight 752 00:30:32,600 --> 00:30:35,120 binary digits eight bits and that's all 753 00:30:35,120 --> 00:30:39,080 a uint 8 is a rune is a Unicode code 754 00:30:39,080 --> 00:30:41,399 point which generally speaking you can 755 00:30:41,399 --> 00:30:43,720 think of as one character in a string 756 00:30:43,720 --> 00:30:45,799 and that's usually how it's used under 757 00:30:45,799 --> 00:30:48,799 the hood it's just an alias for the 758 00:30:48,799 --> 00:30:51,440 int32 type moving on to the assignment 759 00:30:51,440 --> 00:30:53,120 it says initialize the given variables 760 00:30:53,120 --> 00:30:55,440 to int float 64 bu and string 761 00:30:55,440 --> 00:30:58,639 respectively with their zero values and 762 00:30:58,639 --> 00:31:00,919 um as we can see here if we just use VAR 763 00:31:00,919 --> 00:31:03,919 the name of the variable and the type 764 00:31:03,919 --> 00:31:05,639 that should do it so we'll initialize 765 00:31:05,639 --> 00:31:08,000 the variables here so 766 00:31:08,000 --> 00:31:13,679 VAR SMS sending limit is an INT VAR cost 767 00:31:13,679 --> 00:31:18,639 per SMS is a float 768 00:31:18,960 --> 00:31:20,720 64 769 00:31:20,720 --> 00:31:24,559 has as permission is 770 00:31:24,559 --> 00:31:26,200 a 771 00:31:26,200 --> 00:31:28,880 and username 772 00:31:28,880 --> 00:31:32,480 is a string okay cool and all so all of 773 00:31:32,480 --> 00:31:34,159 these variables are now instantiated and 774 00:31:34,159 --> 00:31:36,240 should contain their zero value so for 775 00:31:36,240 --> 00:31:40,360 example zero uh 0.0 false and empty 776 00:31:40,360 --> 00:31:42,799 string so let's go ahead and run 777 00:31:42,799 --> 00:31:45,440 that and that looks correct to me I'm 778 00:31:45,440 --> 00:31:47,960 going to go ahead and submit it we've 779 00:31:47,960 --> 00:31:49,919 been declaring variables the hard way 780 00:31:49,919 --> 00:31:51,720 now we're going to do it the easy way 781 00:31:51,720 --> 00:31:54,559 there is an operator in go colon equals 782 00:31:54,559 --> 00:31:56,639 that is the short assignment operator 783 00:31:56,639 --> 00:31:59,200 and it allows us to to declare variables 784 00:31:59,200 --> 00:32:02,720 and have go infer their type so instead 785 00:32:02,720 --> 00:32:05,720 of typing VAR empty string we can just 786 00:32:05,720 --> 00:32:08,679 say empty colon equals the empty string 787 00:32:08,679 --> 00:32:12,440 and go knows that this has to be a 788 00:32:12,440 --> 00:32:15,840 string so it is a string now when we use 789 00:32:15,840 --> 00:32:18,200 this short assignment operator we're not 790 00:32:18,200 --> 00:32:19,880 saying this is a loose type that can 791 00:32:19,880 --> 00:32:21,600 change in the future it's still a static 792 00:32:21,600 --> 00:32:24,200 type empty is a string just like it 793 00:32:24,200 --> 00:32:26,519 would be if we declared it this way in 794 00:32:26,519 --> 00:32:29,480 reality in go you will very rarely see 795 00:32:29,480 --> 00:32:31,559 variables declared like this you will 796 00:32:31,559 --> 00:32:33,760 almost always see them declared using 797 00:32:33,760 --> 00:32:37,039 the short the short assignment operator 798 00:32:37,039 --> 00:32:40,559 for example num Carson equals 10 creates 799 00:32:40,559 --> 00:32:42,440 a new variable called num cars and sets 800 00:32:42,440 --> 00:32:44,480 it equal to 10 and its type will be 801 00:32:44,480 --> 00:32:47,880 inferred to be an INT and the int type 802 00:32:47,880 --> 00:32:51,039 Alias is either int32 or int64 depending 803 00:32:51,039 --> 00:32:52,880 on your computer's architecture if you 804 00:32:52,880 --> 00:32:55,799 want to specify a particular size of 805 00:32:55,799 --> 00:32:57,960 integer then you would declare it using 806 00:32:57,960 --> 00:33:00,600 this kind of lonand syntax so in this 807 00:33:00,600 --> 00:33:02,760 assignment we're just meant to declare a 808 00:33:02,760 --> 00:33:05,320 variable named congrats with the value 809 00:33:05,320 --> 00:33:07,120 happy birthday using a short variable 810 00:33:07,120 --> 00:33:10,440 declaration so as simple as congrats 811 00:33:10,440 --> 00:33:14,399 colon equals the string happy 812 00:33:14,399 --> 00:33:17,320 birthday let me run 813 00:33:17,320 --> 00:33:19,679 that 814 00:33:19,679 --> 00:33:22,120 perfect this next assignment says our 815 00:33:22,120 --> 00:33:24,559 current price to send a text message in 816 00:33:24,559 --> 00:33:27,559 texo is 2 cents however it's likely in 817 00:33:27,559 --> 00:33:29,080 the future that the price will have to 818 00:33:29,080 --> 00:33:31,080 be a fraction of a penny or have a 819 00:33:31,080 --> 00:33:33,399 fractional part to the cost so we should 820 00:33:33,399 --> 00:33:36,000 use a float 64 to store this value edit 821 00:33:36,000 --> 00:33:38,880 the pennies per text declaration so that 822 00:33:38,880 --> 00:33:40,480 it's inferred by the compiler to be a 823 00:33:40,480 --> 00:33:43,360 float 64 Okay cool so 824 00:33:43,360 --> 00:33:46,639 here we're just setting it equal to two 825 00:33:46,639 --> 00:33:49,559 if I run that then I get the type of 826 00:33:49,559 --> 00:33:53,039 pennies per text is int and this percent 827 00:33:53,039 --> 00:33:58,120 T in go um is is a formatting verb that 828 00:33:58,120 --> 00:33:59,880 that tells the go programming language 829 00:33:59,880 --> 00:34:01,720 or or at least the print F function I 830 00:34:01,720 --> 00:34:03,200 should say the formatting package from 831 00:34:03,200 --> 00:34:05,279 the standard Library um that I want to 832 00:34:05,279 --> 00:34:07,440 print the type of this variable rather 833 00:34:07,440 --> 00:34:08,879 than its value so that's why we're 834 00:34:08,879 --> 00:34:11,399 saying int there instead of 835 00:34:11,399 --> 00:34:14,240 two um to get a float all we need to do 836 00:34:14,240 --> 00:34:18,119 is change it from two to 2.0 I believe 837 00:34:18,119 --> 00:34:19,800 64 838 00:34:19,800 --> 00:34:22,720 cool another handy syntactic Quirk of 839 00:34:22,720 --> 00:34:23,960 the go programming language is that we 840 00:34:23,960 --> 00:34:26,280 can declare multiple values on the same 841 00:34:26,280 --> 00:34:28,119 line so in this assignment it says 842 00:34:28,119 --> 00:34:29,919 declare a float called average open rate 843 00:34:29,919 --> 00:34:32,079 and a string called display message on 844 00:34:32,079 --> 00:34:35,320 the same line okay so average open 845 00:34:35,320 --> 00:34:38,200 rate display 846 00:34:38,200 --> 00:34:41,639 message same line the average open rate 847 00:34:41,639 --> 00:34:44,200 um must 848 00:34:45,639 --> 00:34:48,839 be23 and the display message should be 849 00:34:48,839 --> 00:34:49,960 the 850 00:34:49,960 --> 00:34:52,520 string is the average open rate of your 851 00:34:52,520 --> 00:34:57,760 message and then it looks like 852 00:34:58,680 --> 00:34:59,960 this is just going to print them 853 00:34:59,960 --> 00:35:02,040 together so it's going to say 0.23 is 854 00:35:02,040 --> 00:35:03,880 the average open rate okay cool let's go 855 00:35:03,880 --> 00:35:06,040 ahead and run 856 00:35:06,040 --> 00:35:08,359 that 023 is the average open rate of 857 00:35:08,359 --> 00:35:10,320 your messages that looks correct to 858 00:35:10,320 --> 00:35:13,320 me so we've already briefly talked about 859 00:35:13,320 --> 00:35:15,839 the different type sizes in go right so 860 00:35:15,839 --> 00:35:19,200 we have the int type int 8 int 16 int 32 861 00:35:19,200 --> 00:35:21,320 and int 64 and it's important to 862 00:35:21,320 --> 00:35:24,040 understand that the int type just 863 00:35:24,040 --> 00:35:27,880 aliases int32 or int64 um same with the 864 00:35:27,880 --> 00:35:30,560 uint type just depending on your cpu's 865 00:35:30,560 --> 00:35:32,440 architecture so you might be on a 32 or 866 00:35:32,440 --> 00:35:35,000 a 64-bit machine most modern machines 867 00:35:35,000 --> 00:35:37,520 are going to be 64 bits my 868 00:35:37,520 --> 00:35:39,960 recommendation is that unless you have 869 00:35:39,960 --> 00:35:42,640 an explicit reason to care about the 870 00:35:42,640 --> 00:35:45,000 size right so unless you're trying to 871 00:35:45,000 --> 00:35:47,160 kind of hyper optimize for performance 872 00:35:47,160 --> 00:35:48,520 then you should really just stick to 873 00:35:48,520 --> 00:35:52,240 these four types int uint float 64 and 874 00:35:52,240 --> 00:35:53,680 again if you're working with imaginary 875 00:35:53,680 --> 00:35:56,400 numbers then complex 128 but that's 876 00:35:56,400 --> 00:35:58,960 honestly unlikely so so these three 877 00:35:58,960 --> 00:36:01,839 types are going to do the vast majority 878 00:36:01,839 --> 00:36:03,560 of the heavy lifting when it comes to 879 00:36:03,560 --> 00:36:06,000 working with numbers in go we can also 880 00:36:06,000 --> 00:36:08,000 convert numbers between you know 881 00:36:08,000 --> 00:36:10,000 different number types for example we 882 00:36:10,000 --> 00:36:13,760 could take a an integer 88 and convert 883 00:36:13,760 --> 00:36:16,280 it to a float like this so it become 884 00:36:16,280 --> 00:36:18,680 88.0 right um converting the other way 885 00:36:18,680 --> 00:36:20,000 is a little trickier though because say 886 00:36:20,000 --> 00:36:22,440 we had 88.6 if we were to convert it to 887 00:36:22,440 --> 00:36:24,480 an INT we would lose the point 6 we 888 00:36:24,480 --> 00:36:27,760 would truncate it down to just 88 now 889 00:36:27,760 --> 00:36:29,520 this assignment says our text AO 890 00:36:29,520 --> 00:36:31,440 customers want to know how long they've 891 00:36:31,440 --> 00:36:32,920 had accounts with us follow the 892 00:36:32,920 --> 00:36:34,160 instructions in the comment provided you 893 00:36:34,160 --> 00:36:35,400 will create a new variable called 894 00:36:35,400 --> 00:36:37,359 account age int that will be the 895 00:36:37,359 --> 00:36:39,960 truncated integer version of account age 896 00:36:39,960 --> 00:36:42,800 Okay cool so create a new account age 897 00:36:42,800 --> 00:36:45,520 int here should be the result of casting 898 00:36:45,520 --> 00:36:47,480 account age to an integer so we'll just 899 00:36:47,480 --> 00:36:50,160 do int account age and I would expect 900 00:36:50,160 --> 00:36:53,240 that to be two after casting it because 901 00:36:53,240 --> 00:36:55,839 it should truncate the 6 so let's go 902 00:36:55,839 --> 00:36:58,440 ahead and run that your account has 903 00:36:58,440 --> 00:37:00,839 existed for 2 years yeah that looks good 904 00:37:00,839 --> 00:37:01,920 to 905 00:37:01,920 --> 00:37:04,440 me we already briefly touched on this 906 00:37:04,440 --> 00:37:06,280 but it's worth mentioning again I 907 00:37:06,280 --> 00:37:08,240 recommend that you stick to the I call 908 00:37:08,240 --> 00:37:10,760 them the default types so for example we 909 00:37:10,760 --> 00:37:13,400 know there's um you know five or six I 910 00:37:13,400 --> 00:37:14,560 can't think of it off the top of my head 911 00:37:14,560 --> 00:37:17,359 now different types of inss right int 912 00:37:17,359 --> 00:37:21,240 int 8 int 16 in 32 int 64 I'd recommend 913 00:37:21,240 --> 00:37:23,200 sticking to int unless you have a very 914 00:37:23,200 --> 00:37:26,960 good reason to specify a smaller size 915 00:37:26,960 --> 00:37:29,839 like int 8 or in32 and that's simply so 916 00:37:29,839 --> 00:37:32,440 you avoid cluttering your code with tons 917 00:37:32,440 --> 00:37:34,760 of type conversions that can sometimes 918 00:37:34,760 --> 00:37:37,880 even lead to bugs so unless you need a 919 00:37:37,880 --> 00:37:40,240 smaller type for performance reasons 920 00:37:40,240 --> 00:37:44,680 just use these default types okay so the 921 00:37:44,680 --> 00:37:46,319 question for this assignment is when 922 00:37:46,319 --> 00:37:48,960 should you elect to not use a default 923 00:37:48,960 --> 00:37:51,960 type when either a default or a specific 924 00:37:51,960 --> 00:37:54,079 size will work when my system has lots 925 00:37:54,079 --> 00:37:56,160 of extra Hardware that I want to utilize 926 00:37:56,160 --> 00:37:57,640 or when performance and memory are 927 00:37:57,640 --> 00:38:00,400 primary concern so it's going to be 928 00:38:00,400 --> 00:38:02,359 performance if you have performance 929 00:38:02,359 --> 00:38:06,160 concerns that's the time I would maybe 930 00:38:06,160 --> 00:38:08,599 stray away from the default 931 00:38:08,599 --> 00:38:11,560 types the next question is what does the 932 00:38:11,560 --> 00:38:15,079 size of a type indicate so a float 64 933 00:38:15,079 --> 00:38:19,040 what does 64 mean is it bits bites or 934 00:38:19,040 --> 00:38:23,280 nibbles uh the answer is going to be 935 00:38:23,280 --> 00:38:25,760 bits now it is worth pointing out 936 00:38:25,760 --> 00:38:28,520 nibbles is a real thing so a bite is 8 937 00:38:28,520 --> 00:38:31,520 Bits a nibble is actually Four bits if 938 00:38:31,520 --> 00:38:34,680 you didn't know that fun interesting 939 00:38:34,680 --> 00:38:37,599 trivia aside from variables go also 940 00:38:37,599 --> 00:38:40,440 supports constants which are immutable 941 00:38:40,440 --> 00:38:43,119 values um and in go just like in 942 00:38:43,119 --> 00:38:44,560 JavaScript or typescript we use the 943 00:38:44,560 --> 00:38:47,400 const keyword and constants do not 944 00:38:47,400 --> 00:38:50,119 support the short declaration syntax so 945 00:38:50,119 --> 00:38:52,319 we have to kind of write it all 946 00:38:52,319 --> 00:38:54,560 out okay so getting to the assignment 947 00:38:54,560 --> 00:38:56,280 says use two separate constants 948 00:38:56,280 --> 00:38:57,520 something weird is happening in this 949 00:38:57,520 --> 00:38:59,240 code what should be happening is that we 950 00:38:59,240 --> 00:39:01,680 create two separate constants Premium 951 00:39:01,680 --> 00:39:03,960 plan name and basic plan name right now 952 00:39:03,960 --> 00:39:05,280 looks like we're trying to overwrite one 953 00:39:05,280 --> 00:39:07,720 of them okay cool so on line six we've 954 00:39:07,720 --> 00:39:10,160 got Premium plan name and we're setting 955 00:39:10,160 --> 00:39:11,400 it to Premium plan and then we have 956 00:39:11,400 --> 00:39:14,319 Premium plan name again attempting to 957 00:39:14,319 --> 00:39:17,640 override the value and set it to a new 958 00:39:17,640 --> 00:39:19,680 string if we try to run this we actually 959 00:39:19,680 --> 00:39:22,560 get a compile time error so we're not 960 00:39:22,560 --> 00:39:26,240 allowed to mutate constants in go so 961 00:39:26,240 --> 00:39:28,520 what we should be doing is creating a 962 00:39:28,520 --> 00:39:31,160 separate constant and it should be named 963 00:39:31,160 --> 00:39:34,839 basic plan name let's go ahead and run 964 00:39:34,839 --> 00:39:38,680 that plan Premium plan plan basic plan 965 00:39:38,680 --> 00:39:42,359 looks good to me constants in go are not 966 00:39:42,359 --> 00:39:44,839 the same as constants in JavaScript and 967 00:39:44,839 --> 00:39:46,800 in typescript in JavaScript and 968 00:39:46,800 --> 00:39:48,520 typescript the const keyword really just 969 00:39:48,520 --> 00:39:50,680 means you can't reassign to this 970 00:39:50,680 --> 00:39:52,480 variable but you can compute the 971 00:39:52,480 --> 00:39:54,560 variable or the variable's value at 972 00:39:54,560 --> 00:39:57,839 runtime in go every value 973 00:39:57,839 --> 00:40:00,240 that's stored in a constant must be 974 00:40:00,240 --> 00:40:04,000 known or computed at compile time before 975 00:40:04,000 --> 00:40:06,880 the program runs so if we create this 976 00:40:06,880 --> 00:40:09,240 new constant called my int and set it 977 00:40:09,240 --> 00:40:11,960 equal to 15 within the compiled go 978 00:40:11,960 --> 00:40:14,680 binary effectively this symbol my in 979 00:40:14,680 --> 00:40:17,560 just refers to the static number 980 00:40:17,560 --> 00:40:20,560 15 the cool thing is that we can 981 00:40:20,560 --> 00:40:23,160 actually compute constants like we can 982 00:40:23,160 --> 00:40:24,880 make constants that depend on other 983 00:40:24,880 --> 00:40:28,040 constants but that computation will run 984 00:40:28,040 --> 00:40:30,800 when we compile our code not when we run 985 00:40:30,800 --> 00:40:33,880 our code so for example um I can create 986 00:40:33,880 --> 00:40:36,119 this constant first name Lane last name 987 00:40:36,119 --> 00:40:37,440 Wagner and then I can create a new 988 00:40:37,440 --> 00:40:39,359 constant called full name it's first 989 00:40:39,359 --> 00:40:41,920 name plus a space plus and the last name 990 00:40:41,920 --> 00:40:43,520 and that's really convenient in case I 991 00:40:43,520 --> 00:40:45,760 ever want to change first name uh now I 992 00:40:45,760 --> 00:40:47,079 don't have to change it in two places 993 00:40:47,079 --> 00:40:48,560 right full name will automatically 994 00:40:48,560 --> 00:40:51,280 update but this is only valid because 995 00:40:51,280 --> 00:40:53,920 all of the inputs to this full name 996 00:40:53,920 --> 00:40:55,800 constant first name and last name are 997 00:40:55,800 --> 00:40:58,359 known at compile time so the compiler 998 00:40:58,359 --> 00:41:00,640 can still do the thing it wants to do 999 00:41:00,640 --> 00:41:03,319 which is replace full name with a static 1000 00:41:03,319 --> 00:41:05,480 string right lane space 1001 00:41:05,480 --> 00:41:08,720 Wagner so on to the assignment says 1002 00:41:08,720 --> 00:41:10,599 keeping track of time in a message 1003 00:41:10,599 --> 00:41:12,640 sending application like textio is 1004 00:41:12,640 --> 00:41:14,599 critical imagine getting at a point 1005 00:41:14,599 --> 00:41:17,079 reminder an hour after your doctor's 1006 00:41:17,079 --> 00:41:19,680 visit not very helpful right complete 1007 00:41:19,680 --> 00:41:21,280 the code using a computed constant to 1008 00:41:21,280 --> 00:41:24,160 print the number of seconds in an hour 1009 00:41:24,160 --> 00:41:25,880 okay so we've got the number of seconds 1010 00:41:25,880 --> 00:41:28,640 in a minute is 60 the number of minutes 1011 00:41:28,640 --> 00:41:31,079 in an hour is also 60 so how many 1012 00:41:31,079 --> 00:41:33,400 seconds are in an hour cool well we 1013 00:41:33,400 --> 00:41:37,720 could hardcode this as like 60 * 1014 00:41:37,720 --> 00:41:39,960 60 but the cool thing is we can actually 1015 00:41:39,960 --> 00:41:41,599 compute it because we can say well we 1016 00:41:41,599 --> 00:41:43,160 know the minutes the number of minutes 1017 00:41:43,160 --> 00:41:45,160 in an hour and we know the number of 1018 00:41:45,160 --> 00:41:48,000 seconds in a 1019 00:41:48,000 --> 00:41:50,280 minute and if we multiply those two 1020 00:41:50,280 --> 00:41:51,480 together we should get the number of 1021 00:41:51,480 --> 00:41:54,800 seconds in an hour 1022 00:41:55,800 --> 00:41:59,359 right that looks correct to 1023 00:41:59,359 --> 00:42:03,119 me so I'm obviously a huge go fan but 1024 00:42:03,119 --> 00:42:05,400 formatting strings in go is honestly one 1025 00:42:05,400 --> 00:42:07,680 of my least favorite features of the 1026 00:42:07,680 --> 00:42:08,800 language I think it's one of its 1027 00:42:08,800 --> 00:42:10,640 weaknesses at the moment who knows maybe 1028 00:42:10,640 --> 00:42:12,599 it'll improve in the future the way it's 1029 00:42:12,599 --> 00:42:14,520 done well we essentially have two 1030 00:42:14,520 --> 00:42:16,280 different functions provided to us by 1031 00:42:16,280 --> 00:42:18,440 the standard Library we have print F and 1032 00:42:18,440 --> 00:42:22,319 S printf printf prints a formatted 1033 00:42:22,319 --> 00:42:25,040 string directly to standard out and S 1034 00:42:25,040 --> 00:42:27,960 printf just Returns the formatted string 1035 00:42:27,960 --> 00:42:29,960 as a value basically all string 1036 00:42:29,960 --> 00:42:32,200 formatting in go currently works the 1037 00:42:32,200 --> 00:42:35,280 same way we have these formatting verbs 1038 00:42:35,280 --> 00:42:38,160 things like percent V percent s percent 1039 00:42:38,160 --> 00:42:41,920 D and they're replaced in the string 1040 00:42:41,920 --> 00:42:44,200 template with actual values so for 1041 00:42:44,200 --> 00:42:47,880 example I am percent V years old the 1042 00:42:47,880 --> 00:42:51,000 percent V in this case is replaced by 10 1043 00:42:51,000 --> 00:42:53,760 the first parameter uh that comes after 1044 00:42:53,760 --> 00:42:57,640 the template in the print F function 1045 00:42:57,640 --> 00:43:00,000 here we could also replace with a string 1046 00:43:00,000 --> 00:43:02,160 instead of an integer right I am percent 1047 00:43:02,160 --> 00:43:04,880 V years old way too many for I am way 1048 00:43:04,880 --> 00:43:07,760 too many years old percent V is sort of 1049 00:43:07,760 --> 00:43:11,079 the default formatter it's usually what 1050 00:43:11,079 --> 00:43:13,720 you want assume you don't want to print 1051 00:43:13,720 --> 00:43:15,400 in kind of the default standard way 1052 00:43:15,400 --> 00:43:17,640 using percent V then there are a few 1053 00:43:17,640 --> 00:43:19,800 others um percent S interpolates A 1054 00:43:19,800 --> 00:43:22,680 String percent D interpolates an integer 1055 00:43:22,680 --> 00:43:25,440 in decimal form so for example 10 1056 00:43:25,440 --> 00:43:27,480 becomes the number 10 instead of say in 1057 00:43:27,480 --> 00:43:30,640 binary form uh percent s is for floats 1058 00:43:30,640 --> 00:43:34,000 so you can specify the number of kind of 1059 00:43:34,000 --> 00:43:36,440 places after the decimal point uh that 1060 00:43:36,440 --> 00:43:38,640 you want printed out to the console or 1061 00:43:38,640 --> 00:43:40,680 printed out to The Returned string in 1062 00:43:40,680 --> 00:43:44,680 the case of s printf um so I actually do 1063 00:43:44,680 --> 00:43:47,960 end up using percent F fairly regularly 1064 00:43:47,960 --> 00:43:50,400 when I'm working with floats so onto the 1065 00:43:50,400 --> 00:43:52,079 assignment it says create a new variable 1066 00:43:52,079 --> 00:43:55,480 called MSG online 9 MSG stands for 1067 00:43:55,480 --> 00:43:57,400 message of course um it's a string that 1068 00:43:57,400 --> 00:43:59,160 contains the following High name your 1069 00:43:59,160 --> 00:44:01,480 open rate is open rate percent where 1070 00:44:01,480 --> 00:44:03,280 name is the given name and open rate is 1071 00:44:03,280 --> 00:44:05,079 the open rate rounded to the nearest 1072 00:44:05,079 --> 00:44:08,960 10's place okay so the 10's place is the 1073 00:44:08,960 --> 00:44:11,599 number right after the decimal so let's 1074 00:44:11,599 --> 00:44:14,319 get started here message colon equals 1075 00:44:14,319 --> 00:44:18,119 fmt dos printf so we're going to use S 1076 00:44:18,119 --> 00:44:20,599 printf instead of print F because we 1077 00:44:20,599 --> 00:44:21,920 don't want this value going to standard 1078 00:44:21,920 --> 00:44:24,240 out we want it returned from the 1079 00:44:24,240 --> 00:44:26,680 function so we can save it in the MSG 1080 00:44:26,680 --> 00:44:29,040 variable 1081 00:44:29,200 --> 00:44:31,400 let's just grab this 1082 00:44:31,400 --> 00:44:34,880 template so we'll use percent s we could 1083 00:44:34,880 --> 00:44:37,160 use percent s or percent V here because 1084 00:44:37,160 --> 00:44:39,760 we're just uh interpolating a string and 1085 00:44:39,760 --> 00:44:45,800 we'll do percent um .1 F because we 1086 00:44:45,800 --> 00:44:49,599 want to just print the 1087 00:44:49,599 --> 00:44:52,480 first number after the the decimal point 1088 00:44:52,480 --> 00:44:53,960 right the tenth 1089 00:44:53,960 --> 00:44:58,040 place okay and then we just pass the two 1090 00:44:58,040 --> 00:45:00,800 values as the following parameters or as 1091 00:45:00,800 --> 00:45:04,400 the last two parameters so name and open 1092 00:45:04,400 --> 00:45:07,480 rate right so the first value name will 1093 00:45:07,480 --> 00:45:09,400 go into the first verb the second value 1094 00:45:09,400 --> 00:45:11,559 will go into the second verb let's run 1095 00:45:11,559 --> 00:45:14,359 that see what we get hi s Goodman your 1096 00:45:14,359 --> 00:45:15,640 open rate is 1097 00:45:15,640 --> 00:45:18,680 30.5% that looks good to me let's talk 1098 00:45:18,680 --> 00:45:20,880 about conditionals in go so a 1099 00:45:20,880 --> 00:45:22,079 conditional is just where we are 1100 00:45:22,079 --> 00:45:24,319 checking if a condition is true if it is 1101 00:45:24,319 --> 00:45:26,599 we do one thing if it's not we may do 1102 00:45:26,599 --> 00:45:28,960 another so for example uh here's an if 1103 00:45:28,960 --> 00:45:33,079 statement in go and if this expression 1104 00:45:33,079 --> 00:45:36,440 evaluates to true then we'll run the 1105 00:45:36,440 --> 00:45:38,480 stuff within the curly braces the body 1106 00:45:38,480 --> 00:45:40,119 of the estatement if you're familiar 1107 00:45:40,119 --> 00:45:41,319 with other programming languages like 1108 00:45:41,319 --> 00:45:43,559 JavaScript this is um a very very 1109 00:45:43,559 --> 00:45:45,160 similar syntax the only difference is 1110 00:45:45,160 --> 00:45:47,079 we're not surrounding the height is 1111 00:45:47,079 --> 00:45:49,520 greater than four section with um 1112 00:45:49,520 --> 00:45:53,000 parentheses so again to be clear this 1113 00:45:53,000 --> 00:45:56,200 bit between the if keyword and the curly 1114 00:45:56,200 --> 00:45:59,040 brace um will be evaluated and if it 1115 00:45:59,040 --> 00:46:02,200 evaluates to true then the stuff inside 1116 00:46:02,200 --> 00:46:06,319 the curly braces will be executed um so 1117 00:46:06,319 --> 00:46:08,240 in this case we have the variable height 1118 00:46:08,240 --> 00:46:10,640 and we're using the greater than 1119 00:46:10,640 --> 00:46:12,960 operator um to compare it to the number 1120 00:46:12,960 --> 00:46:15,040 four so if height is greater than four 1121 00:46:15,040 --> 00:46:17,359 then we'll print you are tall enough 1122 00:46:17,359 --> 00:46:19,160 sort of listed um some of the different 1123 00:46:19,160 --> 00:46:21,599 comparison operators uh down here at the 1124 00:46:21,599 --> 00:46:23,800 bottom they are basically identical to 1125 00:46:23,800 --> 00:46:24,839 pretty much every other programming 1126 00:46:24,839 --> 00:46:27,599 language you will uh probably have used 1127 00:46:27,599 --> 00:46:30,520 uh up to this point additionally we can 1128 00:46:30,520 --> 00:46:33,520 do different things um if the if 1129 00:46:33,520 --> 00:46:36,160 statement does not evaluate to true so 1130 00:46:36,160 --> 00:46:37,720 this is a perfectly valid if statement 1131 00:46:37,720 --> 00:46:41,440 you do not need an else if or an else 1132 00:46:41,440 --> 00:46:43,559 block they are they're optional 1133 00:46:43,559 --> 00:46:46,559 effectively um but the way it works is 1134 00:46:46,559 --> 00:46:48,920 when we get to this code uh basically 1135 00:46:48,920 --> 00:46:51,280 we'll we'll uh compare height to six 1136 00:46:51,280 --> 00:46:52,720 right and if that expression evaluates 1137 00:46:52,720 --> 00:46:54,720 to true then we'll just print you are 1138 00:46:54,720 --> 00:46:57,520 super tall and we'll be done 1139 00:46:57,520 --> 00:47:00,319 okay otherwise if that expression 1140 00:47:00,319 --> 00:47:02,559 evaluates to false then we'll drop down 1141 00:47:02,559 --> 00:47:05,880 into this next if else or sorry else if 1142 00:47:05,880 --> 00:47:08,000 statement and we'll compare height to 1143 00:47:08,000 --> 00:47:10,680 four if height is greater than four then 1144 00:47:10,680 --> 00:47:13,440 we'll print you are tall enough and 1145 00:47:13,440 --> 00:47:15,559 again we'll be done at that point so if 1146 00:47:15,559 --> 00:47:18,880 this evaluates to true we execute this 1147 00:47:18,880 --> 00:47:20,400 um kind of section of code between the 1148 00:47:20,400 --> 00:47:23,040 curly braces and at that point we'll be 1149 00:47:23,040 --> 00:47:26,160 done otherwise if that's also false so 1150 00:47:26,160 --> 00:47:28,119 if height is not great than six and 1151 00:47:28,119 --> 00:47:30,359 height is not greater than four then the 1152 00:47:30,359 --> 00:47:33,079 else statement executes notice the else 1153 00:47:33,079 --> 00:47:34,400 statement does not have its own 1154 00:47:34,400 --> 00:47:36,400 expression it just kind of always 1155 00:47:36,400 --> 00:47:39,280 executes if all of the if and else if 1156 00:47:39,280 --> 00:47:42,880 statements um turned out to be false so 1157 00:47:42,880 --> 00:47:44,640 let's jump into the assignment it says 1158 00:47:44,640 --> 00:47:47,119 fix the bug on line 12 the if statement 1159 00:47:47,119 --> 00:47:49,960 should print message sent if the message 1160 00:47:49,960 --> 00:47:53,240 length is less than or equal to the max 1161 00:47:53,240 --> 00:47:55,880 message length or message not sent 1162 00:47:55,880 --> 00:47:58,480 otherwise Okay cool so up here we've 1163 00:47:58,480 --> 00:48:00,280 defined two variables uh message length 1164 00:48:00,280 --> 00:48:03,480 is 10 Max message length is 20 um and 1165 00:48:03,480 --> 00:48:04,839 then here we're going to do some 1166 00:48:04,839 --> 00:48:06,319 comparing let me just run the code in 1167 00:48:06,319 --> 00:48:08,119 its current 1168 00:48:08,119 --> 00:48:10,359 state says trying to send a message of 1169 00:48:10,359 --> 00:48:14,400 length 10 and a max length of 20 message 1170 00:48:14,400 --> 00:48:17,040 not sent okay so that seems problematic 1171 00:48:17,040 --> 00:48:18,720 right because with a message length of 1172 00:48:18,720 --> 00:48:21,559 10 and a Max message length of 20 I 1173 00:48:21,559 --> 00:48:24,400 should be able to send that message so 1174 00:48:24,400 --> 00:48:26,440 the Bug Online 12 I think we just need 1175 00:48:26,440 --> 00:48:28,880 to flip this operator to be less than or 1176 00:48:28,880 --> 00:48:32,520 equal to so that now this expression 1177 00:48:32,520 --> 00:48:34,200 right message length less than or equal 1178 00:48:34,200 --> 00:48:37,640 to Max message length should evaluate to 1179 00:48:37,640 --> 00:48:41,040 true because it is message length is in 1180 00:48:41,040 --> 00:48:44,480 fact smaller okay let's run 1181 00:48:46,240 --> 00:48:49,720 that message sent that seems to work 1182 00:48:49,720 --> 00:48:51,520 it's worth pointing out that in go we 1183 00:48:51,520 --> 00:48:53,400 also have kind of an alternate way to 1184 00:48:53,400 --> 00:48:54,400 write if 1185 00:48:54,400 --> 00:48:57,680 statements if the variable that we are 1186 00:48:57,680 --> 00:49:01,319 comparing in an if statement is only 1187 00:49:01,319 --> 00:49:04,040 used in that if statement then this 1188 00:49:04,040 --> 00:49:06,880 syntax can be helpful okay so here's 1189 00:49:06,880 --> 00:49:08,200 kind of the traditional way of doing 1190 00:49:08,200 --> 00:49:09,799 something we would create a variable 1191 00:49:09,799 --> 00:49:11,319 called length let's just assume it's an 1192 00:49:11,319 --> 00:49:13,160 integer you can kind of forget um this 1193 00:49:13,160 --> 00:49:15,400 function Syntax for now we'll talk about 1194 00:49:15,400 --> 00:49:18,480 it um in a future chapter but basically 1195 00:49:18,480 --> 00:49:19,839 the idea here is we have a length 1196 00:49:19,839 --> 00:49:21,839 variable it's an integer right and we're 1197 00:49:21,839 --> 00:49:23,799 initializing it here we're creating the 1198 00:49:23,799 --> 00:49:26,720 variable here um and then we're compar 1199 00:49:26,720 --> 00:49:27,960 pairing it against one right we're 1200 00:49:27,960 --> 00:49:29,240 checking if it's less than one and if it 1201 00:49:29,240 --> 00:49:30,520 is we're doing something in this case 1202 00:49:30,520 --> 00:49:32,799 we're printing that the email is invalid 1203 00:49:32,799 --> 00:49:35,240 well instead of this syntax and by the 1204 00:49:35,240 --> 00:49:36,599 way this works perfectly fine there's 1205 00:49:36,599 --> 00:49:39,000 nothing wrong with doing it this way um 1206 00:49:39,000 --> 00:49:40,480 but we can alternately do it this way 1207 00:49:40,480 --> 00:49:42,920 which is basically to initialize that 1208 00:49:42,920 --> 00:49:46,319 length variable in the if block within 1209 00:49:46,319 --> 00:49:49,200 that first kind of initial statement so 1210 00:49:49,200 --> 00:49:51,119 notice there's two statements here um 1211 00:49:51,119 --> 00:49:52,319 separated by a 1212 00:49:52,319 --> 00:49:54,400 semicolon and in the first one we're 1213 00:49:54,400 --> 00:49:56,760 creating that length variable and then 1214 00:49:56,760 --> 00:50:00,040 then we're moving the comparison itself 1215 00:50:00,040 --> 00:50:02,920 kind of after the semicolon and then if 1216 00:50:02,920 --> 00:50:05,200 that condition obviously evaluates to 1217 00:50:05,200 --> 00:50:07,559 true then we'll um execute the block 1218 00:50:07,559 --> 00:50:09,000 this does kind of two things for us 1219 00:50:09,000 --> 00:50:11,960 first it saves us a line of code um 1220 00:50:11,960 --> 00:50:13,400 which I would argue probably isn't the 1221 00:50:13,400 --> 00:50:15,920 biggest benefit in the world um but more 1222 00:50:15,920 --> 00:50:18,200 importantly uh it makes it so that this 1223 00:50:18,200 --> 00:50:21,880 length variable is only accessible 1224 00:50:21,880 --> 00:50:24,720 within uh kind of the scope of this if 1225 00:50:24,720 --> 00:50:27,400 block so kind of down under Neath this 1226 00:50:27,400 --> 00:50:29,000 code we wouldn't be able to use the 1227 00:50:29,000 --> 00:50:31,000 length uh variable anymore which is kind 1228 00:50:31,000 --> 00:50:33,480 of nice if you never intended to use it 1229 00:50:33,480 --> 00:50:35,960 in the first place you can kind of think 1230 00:50:35,960 --> 00:50:39,359 of this as a clean code hack or like a 1231 00:50:39,359 --> 00:50:43,240 um kind of safety hack um to ensure that 1232 00:50:43,240 --> 00:50:45,920 the length variable is never reused Down 1233 00:50:45,920 --> 00:50:47,920 Below in other code when you never 1234 00:50:47,920 --> 00:50:51,960 intended it to be reused okay so uh the 1235 00:50:51,960 --> 00:50:53,799 question for this assignment is why 1236 00:50:53,799 --> 00:50:56,119 would you use the initial section of an 1237 00:50:56,119 --> 00:50:58,599 if statement uh and the answers are to 1238 00:50:58,599 --> 00:51:00,000 confuse other programmers to keep the 1239 00:51:00,000 --> 00:51:02,200 code concise and the scope limited or to 1240 00:51:02,200 --> 00:51:04,839 speed up your code um the answer is 1241 00:51:04,839 --> 00:51:06,079 going to be to keep the code more 1242 00:51:06,079 --> 00:51:08,799 concise and to again limit the scope 1243 00:51:08,799 --> 00:51:13,280 that that variable um exists within like 1244 00:51:13,280 --> 00:51:15,520 other programming languages go supports 1245 00:51:15,520 --> 00:51:17,079 functions functions are basically just a 1246 00:51:17,079 --> 00:51:19,240 way to break up your code into 1247 00:51:19,240 --> 00:51:21,880 individual units that are easier to 1248 00:51:21,880 --> 00:51:24,119 reason about right a function takes in a 1249 00:51:24,119 --> 00:51:26,319 specified number of inputs and it 1250 00:51:26,319 --> 00:51:28,040 returns ears a specified number of 1251 00:51:28,040 --> 00:51:30,760 outputs for example this subtract 1252 00:51:30,760 --> 00:51:33,960 function here named sub takes two inputs 1253 00:51:33,960 --> 00:51:36,720 X and integer and Y an integer and it 1254 00:51:36,720 --> 00:51:39,359 returns a single integer in this case it 1255 00:51:39,359 --> 00:51:42,000 just performs the simple calculation x - 1256 00:51:42,000 --> 00:51:44,960 Y and then Returns the result to the CER 1257 00:51:44,960 --> 00:51:47,599 now this little bit right here right 1258 00:51:47,599 --> 00:51:51,440 Funk sub X integer y integer returns 1259 00:51:51,440 --> 00:51:54,079 integer is what's known as the function 1260 00:51:54,079 --> 00:51:55,720 signature if you've never heard that 1261 00:51:55,720 --> 00:51:57,799 term before it's basically just a 1262 00:51:57,799 --> 00:52:01,280 description of what the function does in 1263 00:52:01,280 --> 00:52:03,000 terms of its types in terms of its 1264 00:52:03,000 --> 00:52:05,599 inputs and its outputs and what types 1265 00:52:05,599 --> 00:52:08,000 they are right this basically says this 1266 00:52:08,000 --> 00:52:10,160 is a function called sub it takes an 1267 00:52:10,160 --> 00:52:13,000 integer X and an integer Y and returns 1268 00:52:13,000 --> 00:52:15,319 another integer function signatures are 1269 00:52:15,319 --> 00:52:16,920 great because they tell us how we can 1270 00:52:16,920 --> 00:52:18,880 use the functions really at the end of 1271 00:52:18,880 --> 00:52:20,559 the day if we're the person calling the 1272 00:52:20,559 --> 00:52:22,000 function or the person using the 1273 00:52:22,000 --> 00:52:24,640 function really all we care about is 1274 00:52:24,640 --> 00:52:26,240 what we need to give the function as 1275 00:52:26,240 --> 00:52:28,200 input and what we get out of the 1276 00:52:28,200 --> 00:52:30,359 function in terms of its outputs so a 1277 00:52:30,359 --> 00:52:32,079 function signature basically tells us 1278 00:52:32,079 --> 00:52:34,000 all we need to know about a function to 1279 00:52:34,000 --> 00:52:36,559 be able to use it it omits all of the 1280 00:52:36,559 --> 00:52:38,680 implementation details the stuff with 1281 00:52:38,680 --> 00:52:40,520 within the curly brackets or within the 1282 00:52:40,520 --> 00:52:43,440 body of the function so let's get on to 1283 00:52:43,440 --> 00:52:45,520 the assignment assignment says we often 1284 00:52:45,520 --> 00:52:46,960 need to manipulate strings in our 1285 00:52:46,960 --> 00:52:48,359 messaging app that makes sense right 1286 00:52:48,359 --> 00:52:50,760 we're working with SMS and email uh 1287 00:52:50,760 --> 00:52:52,440 messages within textio so we're doing a 1288 00:52:52,440 --> 00:52:55,880 lot of textual data manipulation the 1289 00:52:55,880 --> 00:52:58,400 concat function should take two strings 1290 00:52:58,400 --> 00:53:00,839 as inputs and smash them together right 1291 00:53:00,839 --> 00:53:02,839 so returning a new string that is a 1292 00:53:02,839 --> 00:53:04,880 concatenation of the inputs for example 1293 00:53:04,880 --> 00:53:08,839 hello Plus World equals hello world so 1294 00:53:08,839 --> 00:53:12,240 we'd expect to return this concatenated 1295 00:53:12,240 --> 00:53:14,760 string from our concat function over 1296 00:53:14,760 --> 00:53:17,559 here fix the function the function 1297 00:53:17,559 --> 00:53:19,480 signature of concat to reflect its 1298 00:53:19,480 --> 00:53:21,240 Behavior Okay cool so let me try running 1299 00:53:21,240 --> 00:53:23,640 this and just see what happens looks 1300 00:53:23,640 --> 00:53:25,440 like undefined 1301 00:53:25,440 --> 00:53:28,480 S1 undefined S2 undefined S1 okay so 1302 00:53:28,480 --> 00:53:29,359 these are 1303 00:53:29,359 --> 00:53:31,000 undefined 1304 00:53:31,000 --> 00:53:33,599 and so S1 and S2 that kind of stands for 1305 00:53:33,599 --> 00:53:35,480 string one string two that makes sense 1306 00:53:35,480 --> 00:53:37,839 the problem here is that we're 1307 00:53:37,839 --> 00:53:40,799 not we're not telling 1308 00:53:40,799 --> 00:53:44,280 go what the types of the inputs should 1309 00:53:44,280 --> 00:53:47,040 be and this plus operator when operating 1310 00:53:47,040 --> 00:53:49,240 on strings just concatenates so that 1311 00:53:49,240 --> 00:53:53,040 should work let's go ahead and run 1312 00:53:54,000 --> 00:53:56,680 that yeah this looks good to me I want 1313 00:53:56,680 --> 00:53:59,319 to just make one more point about 1314 00:53:59,319 --> 00:54:01,319 function signatures in go you'll notice 1315 00:54:01,319 --> 00:54:03,599 that the type comes 1316 00:54:03,599 --> 00:54:06,640 after the name of the variable so S1 is 1317 00:54:06,640 --> 00:54:09,359 a string S2 is a string and that's just 1318 00:54:09,359 --> 00:54:10,839 to make it a little easier to read the 1319 00:54:10,839 --> 00:54:12,440 authors of the go programming language 1320 00:54:12,440 --> 00:54:15,480 kind of built on uh a lot of the ideas 1321 00:54:15,480 --> 00:54:17,720 from C and in C it was the reverse it 1322 00:54:17,720 --> 00:54:21,319 was string S1 string S2 and that just 1323 00:54:21,319 --> 00:54:23,680 kind of reads a little clunky if you're 1324 00:54:23,680 --> 00:54:25,400 used to kind of speaking in plain 1325 00:54:25,400 --> 00:54:27,559 English makes more sense for the type to 1326 00:54:27,559 --> 00:54:30,559 kind of come after um what it describes 1327 00:54:30,559 --> 00:54:32,400 go provides another bit of interesting 1328 00:54:32,400 --> 00:54:33,599 syntactic sugar when it comes to 1329 00:54:33,599 --> 00:54:35,680 function signatures when multiple 1330 00:54:35,680 --> 00:54:37,400 arguments are of the same type in this 1331 00:54:37,400 --> 00:54:39,680 case X and Y the inputs to the add 1332 00:54:39,680 --> 00:54:42,520 function are both integers um the type 1333 00:54:42,520 --> 00:54:44,960 only needs to be declared on the last 1334 00:54:44,960 --> 00:54:46,920 one assuming that they're in order right 1335 00:54:46,920 --> 00:54:49,400 so in this case this is valid go code 1336 00:54:49,400 --> 00:54:52,400 and X and Y are both integers because 1337 00:54:52,400 --> 00:54:54,599 they follow one another we can put the 1338 00:54:54,599 --> 00:54:57,240 integer um just after the y if we were 1339 00:54:57,240 --> 00:54:59,319 going to add say a string as a third 1340 00:54:59,319 --> 00:55:01,240 parameter uh to this function then we 1341 00:55:01,240 --> 00:55:03,599 would just add a comma here after int 1342 00:55:03,599 --> 00:55:05,799 and put you know name String or or 1343 00:55:05,799 --> 00:55:07,440 whatever um this is just a bit of 1344 00:55:07,440 --> 00:55:09,559 syntactic sugar uh it makes our code a 1345 00:55:09,559 --> 00:55:11,760 little less verbose you don't need to do 1346 00:55:11,760 --> 00:55:13,760 this you can explicitly put the type on 1347 00:55:13,760 --> 00:55:15,520 every input and output but you will 1348 00:55:15,520 --> 00:55:17,440 often see code like this it's a 1349 00:55:17,440 --> 00:55:19,799 convenient shorthand so we've got these 1350 00:55:19,799 --> 00:55:23,640 two um example Snippets of code Funk 1351 00:55:23,640 --> 00:55:25,599 create user first name String last name 1352 00:55:25,599 --> 00:55:28,240 String age in and Funk create user first 1353 00:55:28,240 --> 00:55:31,039 name last name String agent so which of 1354 00:55:31,039 --> 00:55:32,799 the following is the most succinct way 1355 00:55:32,799 --> 00:55:34,520 to write a function signature Su synct 1356 00:55:34,520 --> 00:55:37,000 is just another word for kind of it's I 1357 00:55:37,000 --> 00:55:38,920 guess it's the opposite of verbose right 1358 00:55:38,920 --> 00:55:40,880 fewer fewer 1359 00:55:40,880 --> 00:55:43,240 words um it's going to be the one that 1360 00:55:43,240 --> 00:55:45,920 uses the syntactic sugar which is this 1361 00:55:45,920 --> 00:55:47,839 one because we're omitting the string 1362 00:55:47,839 --> 00:55:50,520 keyword after first name so we already 1363 00:55:50,520 --> 00:55:52,839 talked about this briefly the idea that 1364 00:55:52,839 --> 00:55:56,760 in go we specify the type of of a 1365 00:55:56,760 --> 00:55:59,079 variable after the variable name and 1366 00:55:59,079 --> 00:56:01,039 this is you know different from kind of 1367 00:56:01,039 --> 00:56:02,839 the C style way of doing things which if 1368 00:56:02,839 --> 00:56:05,000 you were to declare a variable Y and C 1369 00:56:05,000 --> 00:56:07,720 you would say int Y and really the 1370 00:56:07,720 --> 00:56:09,400 authors of the go programming language 1371 00:56:09,400 --> 00:56:10,839 just felt that that didn't flow 1372 00:56:10,839 --> 00:56:12,799 naturally from English it's not the way 1373 00:56:12,799 --> 00:56:16,680 we talk right we say x is an integer not 1374 00:56:16,680 --> 00:56:20,000 integer is X if you want to read up on 1375 00:56:20,000 --> 00:56:21,960 that decision and why they ended up uh 1376 00:56:21,960 --> 00:56:23,720 choosing that style then you can follow 1377 00:56:23,720 --> 00:56:25,039 this link here assuming you're following 1378 00:56:25,039 --> 00:56:27,680 Along on botev so the question is what 1379 00:56:27,680 --> 00:56:29,480 are we talking about when we discuss 1380 00:56:29,480 --> 00:56:32,200 this declaration syntax right this this 1381 00:56:32,200 --> 00:56:35,920 swapping of the name and the type um and 1382 00:56:35,920 --> 00:56:38,039 here are options the decision about 1383 00:56:38,039 --> 00:56:40,520 Campbell case versus snake case um the 1384 00:56:40,520 --> 00:56:42,200 style of language used to create new 1385 00:56:42,200 --> 00:56:44,599 variables types and functions guard 1386 00:56:44,599 --> 00:56:46,760 Clauses versus if else no the ever 1387 00:56:46,760 --> 00:56:49,119 important question of tabs versus spaces 1388 00:56:49,119 --> 00:56:50,280 no it's going to be the style of 1389 00:56:50,280 --> 00:56:52,079 language used to create new variables 1390 00:56:52,079 --> 00:56:54,359 types and functions related question is 1391 00:56:54,359 --> 00:56:56,839 Which languages declaration syntax reads 1392 00:56:56,839 --> 00:56:59,599 like English from right to left C or go 1393 00:56:59,599 --> 00:57:01,799 the answer is going to be go go supports 1394 00:57:01,799 --> 00:57:04,680 functions as data or basically the idea 1395 00:57:04,680 --> 00:57:06,520 that you can pass functions around your 1396 00:57:06,520 --> 00:57:08,920 program uh to be called in different 1397 00:57:08,920 --> 00:57:10,760 places callbacks right if you're 1398 00:57:10,760 --> 00:57:12,359 familiar with JavaScript then you're 1399 00:57:12,359 --> 00:57:14,240 probably familiar with the idea of a 1400 00:57:14,240 --> 00:57:15,839 callback it's a function that you could 1401 00:57:15,839 --> 00:57:17,880 pass to another function to be called 1402 00:57:17,880 --> 00:57:21,119 later this question deals with that idea 1403 00:57:21,119 --> 00:57:24,480 whenever we pass a call back in go the 1404 00:57:24,480 --> 00:57:27,000 type of the function Chang based on what 1405 00:57:27,000 --> 00:57:29,079 its inputs and outputs are so for 1406 00:57:29,079 --> 00:57:34,160 example here funk in in int is a 1407 00:57:34,160 --> 00:57:36,119 function that takes two integers as an 1408 00:57:36,119 --> 00:57:38,440 input and returns an integer and that's 1409 00:57:38,440 --> 00:57:41,680 going to be a different type than a 1410 00:57:41,680 --> 00:57:44,000 function that say took three integers as 1411 00:57:44,000 --> 00:57:46,599 input and returned an integer and if you 1412 00:57:46,599 --> 00:57:48,319 think about it it makes sense right if 1413 00:57:48,319 --> 00:57:50,359 I'm going to pass a function to another 1414 00:57:50,359 --> 00:57:52,599 function so that it can call it later it 1415 00:57:52,599 --> 00:57:54,720 kind of needs to know how many inputs 1416 00:57:54,720 --> 00:57:56,880 how many parameters it can pass into 1417 00:57:56,880 --> 00:57:58,839 that function if it's a function that 1418 00:57:58,839 --> 00:58:01,240 takes two inputs versus three inputs 1419 00:58:01,240 --> 00:58:02,839 then the caller is going to have to 1420 00:58:02,839 --> 00:58:05,400 write the code differently so we have to 1421 00:58:05,400 --> 00:58:08,000 treat every function signature as its 1422 00:58:08,000 --> 00:58:10,920 own unique type so this question is a 1423 00:58:10,920 --> 00:58:12,920 bit of a doozy I encourage you to pause 1424 00:58:12,920 --> 00:58:14,319 the video and try to work this one out 1425 00:58:14,319 --> 00:58:16,520 on your own um but basically it says 1426 00:58:16,520 --> 00:58:20,720 what is this hairy beast here right F 1427 00:58:20,720 --> 00:58:23,720 Funk Funk int int int int 1428 00:58:23,720 --> 00:58:27,559 int all right potential answers are a 1429 00:58:27,559 --> 00:58:30,599 function named F that takes as int takes 1430 00:58:30,599 --> 00:58:33,200 an INT as the argument and returns an 1431 00:58:33,200 --> 00:58:36,559 INT uh no it is not nearly that simple 1432 00:58:36,559 --> 00:58:39,480 right a function named F that takes a 1433 00:58:39,480 --> 00:58:42,599 function and an INT as arguments and 1434 00:58:42,599 --> 00:58:44,799 returns a function let's 1435 00:58:44,799 --> 00:58:48,039 see uh that right there is a full 1436 00:58:48,039 --> 00:58:51,400 function and an INT as arguments and 1437 00:58:51,400 --> 00:58:53,960 returns a function no this returns an 1438 00:58:53,960 --> 00:58:56,559 INT okay a function named f that takes a 1439 00:58:56,559 --> 00:58:58,200 function and an INT as arguments and 1440 00:58:58,200 --> 00:59:00,039 returns an INT that's what I believe it 1441 00:59:00,039 --> 00:59:02,559 will be function named F that takes a 1442 00:59:02,559 --> 00:59:04,559 function as the argument and returns an 1443 00:59:04,559 --> 00:59:08,799 INT yep that's not it so ju to be clear 1444 00:59:08,799 --> 00:59:12,400 f is a function it takes two 1445 00:59:12,400 --> 00:59:14,200 parameters a 1446 00:59:14,200 --> 00:59:16,480 function right a function of a specific 1447 00:59:16,480 --> 00:59:18,960 type a function that takes two ins and 1448 00:59:18,960 --> 00:59:21,640 returns an INT and as its second 1449 00:59:21,640 --> 00:59:25,359 parameter an INT and then F returns an 1450 00:59:25,359 --> 00:59:26,599 INT 1451 00:59:26,599 --> 00:59:28,280 hopefully that makes sense again feel 1452 00:59:28,280 --> 00:59:30,319 free to pause the video and and stare at 1453 00:59:30,319 --> 00:59:32,760 that for a second let's talk a little 1454 00:59:32,760 --> 00:59:36,079 bit about memory and how data that we 1455 00:59:36,079 --> 00:59:38,799 create in our program using variables is 1456 00:59:38,799 --> 00:59:42,720 stored in memory so over here I'll keep 1457 00:59:42,720 --> 00:59:45,079 track of the memory of our program and 1458 00:59:45,079 --> 00:59:47,599 over here I'll write some 1459 00:59:47,599 --> 00:59:52,799 code so let's say in our code we write X 1460 00:59:52,799 --> 00:59:55,559 colon equals 5 right so we're creating a 1461 00:59:55,559 --> 00:59:58,440 new variable called X and we are giving 1462 00:59:58,440 --> 01:00:01,079 it the value the integer value of five 1463 01:00:01,079 --> 01:00:04,160 and then we're placing the value 1464 01:00:04,160 --> 01:00:07,559 five in that memory right stored as 1465 01:00:07,559 --> 01:00:11,000 binary data within Ram now in our 1466 01:00:11,000 --> 01:00:14,440 program X the symbol is essentially just 1467 01:00:14,440 --> 01:00:16,000 a 1468 01:00:16,000 --> 01:00:19,640 pointer it points to this location in 1469 01:00:19,640 --> 01:00:22,319 memory so let's say on the next line of 1470 01:00:22,319 --> 01:00:26,039 code we update X and we say x equal 2 so 1471 01:00:26,039 --> 01:00:28,680 now we're reassigning the value of x to 1472 01:00:28,680 --> 01:00:31,280 two now let's try something different 1473 01:00:31,280 --> 01:00:34,400 what if we create a new variable called 1474 01:00:34,400 --> 01:00:37,559 Y and we initialize it to the current 1475 01:00:37,559 --> 01:00:40,200 value of x which in this case happens to 1476 01:00:40,200 --> 01:00:43,240 be two well in this 1477 01:00:43,240 --> 01:00:46,000 case we're actually going to allocate a 1478 01:00:46,000 --> 01:00:48,799 new section of memory to store the value 1479 01:00:48,799 --> 01:00:51,680 of y and we'll initialize it to the 1480 01:00:51,680 --> 01:00:56,359 current value of x which is two 1481 01:00:56,799 --> 01:00:58,880 and the symbol 1482 01:00:58,880 --> 01:01:03,799 y now has its own location in memory so 1483 01:01:03,799 --> 01:01:07,880 we basically created a copy of X now 1484 01:01:07,880 --> 01:01:10,520 this idea is really important to 1485 01:01:10,520 --> 01:01:12,480 understand because sometimes in 1486 01:01:12,480 --> 01:01:14,640 programming we'll have multiple 1487 01:01:14,640 --> 01:01:16,720 variables that actually point to the 1488 01:01:16,720 --> 01:01:18,799 same location in memory they can 1489 01:01:18,799 --> 01:01:21,359 overwrite each other and sometimes we 1490 01:01:21,359 --> 01:01:24,680 don't sometimes we have copies of data 1491 01:01:24,680 --> 01:01:26,680 right so now for example if I were to 1492 01:01:26,680 --> 01:01:31,440 update y let's say I made y equal 1 at 1493 01:01:31,440 --> 01:01:34,359 this point x would be unaffected X would 1494 01:01:34,359 --> 01:01:38,680 remain two but y now becomes one right 1495 01:01:38,680 --> 01:01:41,119 because we have a copy these two 1496 01:01:41,119 --> 01:01:43,680 variables X and Y reference different 1497 01:01:43,680 --> 01:01:46,160 locations in memory so why does all of 1498 01:01:46,160 --> 01:01:48,599 this matter well in go variables are 1499 01:01:48,599 --> 01:01:51,520 passed by value not by reference so 1500 01:01:51,520 --> 01:01:53,880 let's take a look at this code snippet 1501 01:01:53,880 --> 01:01:56,559 here top of main we deare a new variable 1502 01:01:56,559 --> 01:01:58,520 called X we set it equal to 5 and then 1503 01:01:58,520 --> 01:02:01,079 we pass X into a function called 1504 01:02:01,079 --> 01:02:03,440 increment the increment function just 1505 01:02:03,440 --> 01:02:07,119 adds one to X right making it six after 1506 01:02:07,119 --> 01:02:10,799 that we print X and the weird thing is 1507 01:02:10,799 --> 01:02:13,160 that when we print X here we still get 1508 01:02:13,160 --> 01:02:17,000 five and the reason for that is the 1509 01:02:17,000 --> 01:02:19,200 increment function was operating on a 1510 01:02:19,200 --> 01:02:22,839 copy of X when we pass X in here to 1511 01:02:22,839 --> 01:02:25,440 increment increment gets a new copy of X 1512 01:02:25,440 --> 01:02:28,960 still equal to 5 it increments that X to 1513 01:02:28,960 --> 01:02:31,359 6 and then because we are not returning 1514 01:02:31,359 --> 01:02:33,680 it it essentially just gets thrown away 1515 01:02:33,680 --> 01:02:35,599 and then back in main we still have this 1516 01:02:35,599 --> 01:02:38,079 same X that's still equal to five the 1517 01:02:38,079 --> 01:02:40,079 correct thing to do here would be to 1518 01:02:40,079 --> 01:02:42,839 have the increment function return X 1519 01:02:42,839 --> 01:02:46,160 after making its modification and up in 1520 01:02:46,160 --> 01:02:49,880 main we would write x equals increment X 1521 01:02:49,880 --> 01:02:51,720 so that we could capture the return 1522 01:02:51,720 --> 01:02:53,839 value from the increment function so 1523 01:02:53,839 --> 01:02:55,440 moving on to the assignment it says it's 1524 01:02:55,440 --> 01:02:58,000 critical in texo that we keep track of 1525 01:02:58,000 --> 01:03:00,240 how many SMS messages we have sent on 1526 01:03:00,240 --> 01:03:02,480 behalf of our clients fix the bug to 1527 01:03:02,480 --> 01:03:04,200 accurately track the number of SMS 1528 01:03:04,200 --> 01:03:06,520 messages sent okay let me just try 1529 01:03:06,520 --> 01:03:08,520 running this in its current 1530 01:03:08,520 --> 01:03:11,000 state and we're missing a 1531 01:03:11,000 --> 01:03:14,200 return okay I'm going to remove 1532 01:03:14,200 --> 01:03:17,720 this this uh type return there and see 1533 01:03:17,720 --> 01:03:21,480 what happens sent 430 1534 01:03:21,480 --> 01:03:23,559 messages and it looks like here we have 1535 01:03:23,559 --> 01:03:27,680 sends so far sends to add increment S is 1536 01:03:27,680 --> 01:03:31,640 doing nothing because s so far is still 1537 01:03:31,640 --> 01:03:34,160 printing as 1538 01:03:34,160 --> 01:03:36,680 430 okay I think I'm understanding so 1539 01:03:36,680 --> 01:03:39,319 let me put that back in the assignment 1540 01:03:39,319 --> 01:03:41,880 says alter increment sends so that it 1541 01:03:41,880 --> 01:03:43,520 Returns the result after incrementing 1542 01:03:43,520 --> 01:03:44,760 sends so 1543 01:03:44,760 --> 01:03:47,319 far alter the main function to capture 1544 01:03:47,319 --> 01:03:49,200 the return value from increment sends 1545 01:03:49,200 --> 01:03:51,640 and overwrite the previous sends so far 1546 01:03:51,640 --> 01:03:53,319 value Okay cool so this is pretty 1547 01:03:53,319 --> 01:03:55,880 similar to the code snippet here 1548 01:03:55,880 --> 01:03:57,920 basically we need to return an INT so 1549 01:03:57,920 --> 01:03:59,240 we're going to 1550 01:03:59,240 --> 01:04:01,760 return send so 1551 01:04:01,760 --> 01:04:05,839 far and then here we need to reassign 1552 01:04:05,839 --> 01:04:09,319 sense so far into the result of 1553 01:04:09,319 --> 01:04:13,079 increment sense cool 1554 01:04:13,079 --> 01:04:15,799 so again here we'll still be operating 1555 01:04:15,799 --> 01:04:18,480 on copies but because we're going to 1556 01:04:18,480 --> 01:04:20,480 return the copy and save it back into 1557 01:04:20,480 --> 01:04:22,359 the original variable we should be good 1558 01:04:22,359 --> 01:04:24,160 to go let me run 1559 01:04:24,160 --> 01:04:27,760 that yep you've sent 455 messages that 1560 01:04:27,760 --> 01:04:30,319 looks correct functions in go can have 1561 01:04:30,319 --> 01:04:32,839 multiple return values and when they do 1562 01:04:32,839 --> 01:04:35,359 have multiple return values the Syntax 1563 01:04:35,359 --> 01:04:37,359 for specifying that is just to wrap the 1564 01:04:37,359 --> 01:04:40,720 return values in parentheses as well so 1565 01:04:40,720 --> 01:04:42,799 when there's just a single return value 1566 01:04:42,799 --> 01:04:44,799 we do not wrap that return value in 1567 01:04:44,799 --> 01:04:47,119 parenthesis but when there are multiples 1568 01:04:47,119 --> 01:04:49,480 we do wrap them in parenthesis one thing 1569 01:04:49,480 --> 01:04:51,920 I really like about go is that it does 1570 01:04:51,920 --> 01:04:55,480 not allow you to have unused variables 1571 01:04:55,480 --> 01:04:57,240 and because it doesn't allow you to have 1572 01:04:57,240 --> 01:04:59,599 unused variables and because it allows 1573 01:04:59,599 --> 01:05:01,359 you to have multiple return values from 1574 01:05:01,359 --> 01:05:03,279 a function we kind of need a way to 1575 01:05:03,279 --> 01:05:05,279 ignore some of the return values because 1576 01:05:05,279 --> 01:05:07,200 there are definitely instances where a 1577 01:05:07,200 --> 01:05:09,279 function returns two things but maybe we 1578 01:05:09,279 --> 01:05:11,359 only care about one of those things for 1579 01:05:11,359 --> 01:05:13,760 example a point on a graph can be 1580 01:05:13,760 --> 01:05:16,680 described by its XY coordinates but 1581 01:05:16,680 --> 01:05:18,559 maybe all we care about is the x 1582 01:05:18,559 --> 01:05:20,760 coordinate so here we can call the get 1583 01:05:20,760 --> 01:05:23,880 Point function and ignore the Y value by 1584 01:05:23,880 --> 01:05:25,920 using an underscore and it's important 1585 01:05:25,920 --> 01:05:27,920 to understand that the underscore is not 1586 01:05:27,920 --> 01:05:30,160 just like a conventional name that we're 1587 01:05:30,160 --> 01:05:32,279 going to ignore it's actually ignored 1588 01:05:32,279 --> 01:05:33,079 the 1589 01:05:33,079 --> 01:05:35,599 compiler completely removes it from our 1590 01:05:35,599 --> 01:05:38,400 code so moving on to the assignment here 1591 01:05:38,400 --> 01:05:40,599 in texo we have obviously first names 1592 01:05:40,599 --> 01:05:42,559 and last names for all of the users that 1593 01:05:42,559 --> 01:05:44,920 we're able to send messages to well when 1594 01:05:44,920 --> 01:05:47,920 we welcome someone to texo we don't need 1595 01:05:47,920 --> 01:05:50,119 their last name so let me go ahead and 1596 01:05:50,119 --> 01:05:52,319 try to run this code and you'll see 1597 01:05:52,319 --> 01:05:53,680 we'll actually get a compiler error that 1598 01:05:53,680 --> 01:05:55,680 says last name declared and not used 1599 01:05:55,680 --> 01:05:58,839 used like I said go does not allow us to 1600 01:05:58,839 --> 01:06:01,520 have unused variables which I think is 1601 01:06:01,520 --> 01:06:03,880 kind of an awesome uh little bit of the 1602 01:06:03,880 --> 01:06:05,559 tooling it helps keep our code very 1603 01:06:05,559 --> 01:06:08,839 clean and concise easy to understand um 1604 01:06:08,839 --> 01:06:12,160 so we need to explicitly ignore that 1605 01:06:12,160 --> 01:06:13,680 last name with an underscore if we're 1606 01:06:13,680 --> 01:06:15,559 not going to use it let me try running 1607 01:06:15,559 --> 01:06:19,400 that again and that looks good to me in 1608 01:06:19,400 --> 01:06:22,599 go we can name our return values and if 1609 01:06:22,599 --> 01:06:25,160 we do it actually Alters the behavior of 1610 01:06:25,160 --> 01:06:26,079 the function 1611 01:06:26,079 --> 01:06:28,039 just a little bit let's take a look at 1612 01:06:28,039 --> 01:06:30,079 this function get chords or get 1613 01:06:30,079 --> 01:06:32,920 coordinates it returns two integers and 1614 01:06:32,920 --> 01:06:36,680 we've named the integers X and Y and by 1615 01:06:36,680 --> 01:06:39,039 naming them we've actually initialized 1616 01:06:39,039 --> 01:06:41,680 at the top of the function the the 1617 01:06:41,680 --> 01:06:43,680 variables X and Y and they're 1618 01:06:43,680 --> 01:06:45,839 initialized with their zero values so in 1619 01:06:45,839 --> 01:06:47,680 the case of an integer literally just 1620 01:06:47,680 --> 01:06:50,039 the number zero for both of them the 1621 01:06:50,039 --> 01:06:52,359 other interesting thing about naming our 1622 01:06:52,359 --> 01:06:55,839 return values is that if we use a naked 1623 01:06:55,839 --> 01:06:58,440 return statement a return statement that 1624 01:06:58,440 --> 01:07:01,039 doesn't explicitly say for example 1625 01:07:01,039 --> 01:07:06,279 return 0 comma 5 then the values of X 1626 01:07:06,279 --> 01:07:09,079 and Y are automatically returned from 1627 01:07:09,079 --> 01:07:10,880 the function 1628 01:07:10,880 --> 01:07:14,400 so this version of get coordinates is 1629 01:07:14,400 --> 01:07:17,279 actually the exact same as this kind of 1630 01:07:17,279 --> 01:07:20,279 more verbose version of get coordinates 1631 01:07:20,279 --> 01:07:22,480 right here we have not given the return 1632 01:07:22,480 --> 01:07:24,559 values the names X and Y and instead 1633 01:07:24,559 --> 01:07:26,960 we've initialized X and Y to their zero 1634 01:07:26,960 --> 01:07:30,240 values and then returned them explicitly 1635 01:07:30,240 --> 01:07:32,400 now a couple of recommendations I would 1636 01:07:32,400 --> 01:07:35,839 recommend using named returns when you 1637 01:07:35,839 --> 01:07:38,520 want to document kind of what the 1638 01:07:38,520 --> 01:07:42,240 intended purpose of each return value is 1639 01:07:42,240 --> 01:07:43,920 so for example if you have a function 1640 01:07:43,920 --> 01:07:46,079 that just returns three integers that 1641 01:07:46,079 --> 01:07:47,799 function signature could be pretty 1642 01:07:47,799 --> 01:07:49,559 confusing but if you have a function 1643 01:07:49,559 --> 01:07:51,319 signature that says it returns three 1644 01:07:51,319 --> 01:07:53,799 integers and they're named width height 1645 01:07:53,799 --> 01:07:56,520 and length that's a lot more interesting 1646 01:07:56,520 --> 01:07:58,319 to the caller of the function they 1647 01:07:58,319 --> 01:07:59,920 understand the purpose of each 1648 01:07:59,920 --> 01:08:02,680 individual return value much better so I 1649 01:08:02,680 --> 01:08:05,119 like to think of named return values as 1650 01:08:05,119 --> 01:08:07,520 basically a built-in way of documenting 1651 01:08:07,520 --> 01:08:09,559 what the purpose of all of your return 1652 01:08:09,559 --> 01:08:11,160 values are and you should generally just 1653 01:08:11,160 --> 01:08:14,160 use them on the other hand this implicit 1654 01:08:14,160 --> 01:08:17,359 or automatic return that you get along 1655 01:08:17,359 --> 01:08:20,040 with um named return values I would 1656 01:08:20,040 --> 01:08:22,199 typically advise against you'd only want 1657 01:08:22,199 --> 01:08:24,239 to use this in like very short very 1658 01:08:24,239 --> 01:08:27,000 simple functions um because it harms 1659 01:08:27,000 --> 01:08:28,560 readability right and I'm pulling this 1660 01:08:28,560 --> 01:08:30,560 directly from the tour of go they also 1661 01:08:30,560 --> 01:08:34,080 agree with me um implicit returns or 1662 01:08:34,080 --> 01:08:36,759 naked return statements um generally a 1663 01:08:36,759 --> 01:08:38,839 little bit harder to understand so the 1664 01:08:38,839 --> 01:08:40,080 way I would write this function 1665 01:08:40,080 --> 01:08:42,880 personally would be get chords XY in and 1666 01:08:42,880 --> 01:08:46,159 then I would explicitly return X and Y 1667 01:08:46,159 --> 01:08:48,319 so let's jump down into the assignment 1668 01:08:48,319 --> 01:08:49,920 it says one of our clients likes us to 1669 01:08:49,920 --> 01:08:51,920 send text messages reminding users of 1670 01:08:51,920 --> 01:08:54,319 Life events coming up fix the bug by 1671 01:08:54,319 --> 01:08:55,960 using named return values in the 1672 01:08:55,960 --> 01:08:57,520 function signature so the code will 1673 01:08:57,520 --> 01:09:00,719 compile and run as intended Okay cool so 1674 01:09:00,719 --> 01:09:02,440 this is the function we are interested 1675 01:09:02,440 --> 01:09:05,600 in fixing years until events looks like 1676 01:09:05,600 --> 01:09:08,679 it takes a user's age as input and then 1677 01:09:08,679 --> 01:09:11,120 returns or should return kind of the 1678 01:09:11,120 --> 01:09:13,199 number of years until they're an adult 1679 01:09:13,199 --> 01:09:15,040 which is 18 the number of years until 1680 01:09:15,040 --> 01:09:17,080 they can drink at least in the US which 1681 01:09:17,080 --> 01:09:19,319 is 21 and the number of years until they 1682 01:09:19,319 --> 01:09:23,319 can rent a car which apparently is 25 um 1683 01:09:23,319 --> 01:09:25,799 and it looks like we never want a 1684 01:09:25,799 --> 01:09:29,640 negative number so if if any of these 1685 01:09:29,640 --> 01:09:31,159 are less than zero we just set them 1686 01:09:31,159 --> 01:09:33,799 equal to zero that makes sense once 1687 01:09:33,799 --> 01:09:36,920 you're over 18 your years until you're 1688 01:09:36,920 --> 01:09:38,640 an adult are just zero right you're 1689 01:09:38,640 --> 01:09:41,040 already an adult okay let me try running 1690 01:09:41,040 --> 01:09:42,920 this see what we get okay undefined 1691 01:09:42,920 --> 01:09:45,560 years until adult all right this makes 1692 01:09:45,560 --> 01:09:48,239 sense right because there's no colon 1693 01:09:48,239 --> 01:09:49,480 here so we're not defining a new 1694 01:09:49,480 --> 01:09:52,000 variable and the assignment said to use 1695 01:09:52,000 --> 01:09:53,640 named return values so let's go ahead 1696 01:09:53,640 --> 01:09:57,320 and do that so here's until adult years 1697 01:09:57,320 --> 01:10:00,800 until drinking I'm going to format this 1698 01:10:00,800 --> 01:10:03,239 a little 1699 01:10:03,440 --> 01:10:07,120 better and we'll do years until car 1700 01:10:07,120 --> 01:10:10,000 rental so again this will declare all of 1701 01:10:10,000 --> 01:10:11,600 these values with their zero value at 1702 01:10:11,600 --> 01:10:13,679 the top and then this naked return 1703 01:10:13,679 --> 01:10:16,679 statement should return them in 1704 01:10:16,679 --> 01:10:19,360 order and just to make sure adult 1705 01:10:19,360 --> 01:10:21,000 drinking car 1706 01:10:21,000 --> 01:10:23,239 rental adult drinking car rental okay 1707 01:10:23,239 --> 01:10:27,320 we're in the right order let me run that 1708 01:10:29,239 --> 01:10:31,640 first test so four years old they'll be 1709 01:10:31,640 --> 01:10:34,239 an adult in 18 years can drink in 17 can 1710 01:10:34,239 --> 01:10:37,280 the current 21 that all looks good 10 1711 01:10:37,280 --> 01:10:39,360 it's going down 1712 01:10:39,360 --> 01:10:42,400 22 Yep this looks good to me so as I 1713 01:10:42,400 --> 01:10:45,000 mentioned before explicit returns are 1714 01:10:45,000 --> 01:10:47,600 probably better than implicit returns in 1715 01:10:47,600 --> 01:10:49,880 most scenarios um it just makes a lot 1716 01:10:49,880 --> 01:10:52,239 more sense right so here in this 1717 01:10:52,239 --> 01:10:54,520 function get chords XY in so we're using 1718 01:10:54,520 --> 01:10:55,760 named return 1719 01:10:55,760 --> 01:10:58,480 but we're still explicitly returning X 1720 01:10:58,480 --> 01:11:01,199 and Y this is how I would recommend 1721 01:11:01,199 --> 01:11:04,360 writing most of your go code 1722 01:11:04,360 --> 01:11:07,560 um this this function here is doing the 1723 01:11:07,560 --> 01:11:10,040 same thing um it's explicitly returning 1724 01:11:10,040 --> 01:11:12,400 hardcoded values though instead of the 1725 01:11:12,400 --> 01:11:14,880 variables X and Y and it's just 1726 01:11:14,880 --> 01:11:16,040 important to understand that this 1727 01:11:16,040 --> 01:11:18,600 effectively overrides the implicit 1728 01:11:18,600 --> 01:11:21,040 return of X and Y so in this case five 1729 01:11:21,040 --> 01:11:23,480 and six will be returned again that's 1730 01:11:23,480 --> 01:11:24,880 why I recommend doing it explicitly 1731 01:11:24,880 --> 01:11:26,600 because when you see a return statement 1732 01:11:26,600 --> 01:11:29,719 that has explicit values being returned 1733 01:11:29,719 --> 01:11:30,920 those are the ones that are returned you 1734 01:11:30,920 --> 01:11:32,120 don't have to do any guess work you 1735 01:11:32,120 --> 01:11:33,360 don't have to scroll back to the top of 1736 01:11:33,360 --> 01:11:34,920 the function to see which values are 1737 01:11:34,920 --> 01:11:36,880 being returned so now we're going to 1738 01:11:36,880 --> 01:11:39,159 break that advice just for practice's 1739 01:11:39,159 --> 01:11:41,520 sake um the assignment says fix the 1740 01:11:41,520 --> 01:11:43,520 function to return the named values 1741 01:11:43,520 --> 01:11:45,520 implicitly okay so here we have a 1742 01:11:45,520 --> 01:11:47,199 problem in our code where we are 1743 01:11:47,199 --> 01:11:50,480 basically explicitly returning zeros 1744 01:11:50,480 --> 01:11:52,800 which as we talked about overrides the 1745 01:11:52,800 --> 01:11:54,639 implicit return so my guess is if we 1746 01:11:54,639 --> 01:11:56,040 look at all of these 1747 01:11:56,040 --> 01:11:59,600 yep every test is returning zeros if we 1748 01:11:59,600 --> 01:12:03,760 just remove that implicit return and run 1749 01:12:03,760 --> 01:12:08,199 that then it should work as intended yep 1750 01:12:08,199 --> 01:12:09,679 and then just to show you what I mean 1751 01:12:09,679 --> 01:12:13,840 like what I would recommend doing is 1752 01:12:16,239 --> 01:12:18,880 this it's 1753 01:12:18,880 --> 01:12:21,120 bigger like that that's how I'm going to 1754 01:12:21,120 --> 01:12:23,120 recommend doing it and in fact because 1755 01:12:23,120 --> 01:12:25,960 Boot Dev just checks the output this 1756 01:12:25,960 --> 01:12:28,120 should work just fine with our test so 1757 01:12:28,120 --> 01:12:31,320 I'm going to submit it like 1758 01:12:31,320 --> 01:12:34,199 this moving on to some questions about 1759 01:12:34,199 --> 01:12:36,440 named returns so it says when should 1760 01:12:36,440 --> 01:12:40,080 naked returns be used and the answers 1761 01:12:40,080 --> 01:12:41,679 are for large functions for small 1762 01:12:41,679 --> 01:12:44,440 functions or for complex functions and I 1763 01:12:44,440 --> 01:12:46,440 would argue if you're going to use naked 1764 01:12:46,440 --> 01:12:47,920 returns at all which honestly I'd kind 1765 01:12:47,920 --> 01:12:49,320 of just recommend against then you 1766 01:12:49,320 --> 01:12:51,920 should only use them for small functions 1767 01:12:51,920 --> 01:12:53,400 the more complex and large your 1768 01:12:53,400 --> 01:12:54,920 functions get the more important it is 1769 01:12:54,920 --> 01:12:57,920 to be explicit and readable and document 1770 01:12:57,920 --> 01:12:59,600 your returns with named returns and 1771 01:12:59,600 --> 01:13:01,600 things like that the next question is 1772 01:13:01,600 --> 01:13:04,560 when should named returns be used so 1773 01:13:04,560 --> 01:13:06,080 when there are many values being 1774 01:13:06,080 --> 01:13:08,360 returned when the function is simple or 1775 01:13:08,360 --> 01:13:10,280 when there are few parameters being 1776 01:13:10,280 --> 01:13:13,360 returned I would argue it's never really 1777 01:13:13,360 --> 01:13:16,320 a problem to name your return values but 1778 01:13:16,320 --> 01:13:18,080 it's really important when there are 1779 01:13:18,080 --> 01:13:20,000 many values being returned especially if 1780 01:13:20,000 --> 01:13:22,440 there are many values of the same type 1781 01:13:22,440 --> 01:13:24,520 being returned because then you can you 1782 01:13:24,520 --> 01:13:26,400 know essentially tell the collar of your 1783 01:13:26,400 --> 01:13:28,360 function through your function signature 1784 01:13:28,360 --> 01:13:30,159 what they should expect each value to 1785 01:13:30,159 --> 01:13:31,920 represent let's talk about one of my 1786 01:13:31,920 --> 01:13:34,120 favorite programming patterns or 1787 01:13:34,120 --> 01:13:36,320 programming Styles um that is early 1788 01:13:36,320 --> 01:13:38,199 returns or um what they're also 1789 01:13:38,199 --> 01:13:40,600 sometimes called as guard Clauses so an 1790 01:13:40,600 --> 01:13:42,920 early return or a guard Clause is 1791 01:13:42,920 --> 01:13:44,480 exactly what it sounds like it's just 1792 01:13:44,480 --> 01:13:47,520 when we return early from a function so 1793 01:13:47,520 --> 01:13:50,159 this function divide if it's past a 1794 01:13:50,159 --> 01:13:53,639 divisor of zero then it returns early 1795 01:13:53,639 --> 01:13:56,040 with an error other wise it goes ahead 1796 01:13:56,040 --> 01:13:58,480 and does kind of the division and 1797 01:13:58,480 --> 01:14:01,360 returns uh the results and a nil error 1798 01:14:01,360 --> 01:14:03,440 now we're going to talk about errors 1799 01:14:03,440 --> 01:14:05,000 soon you don't have to worry too much 1800 01:14:05,000 --> 01:14:07,639 about how they work for now um just 1801 01:14:07,639 --> 01:14:09,480 understand that a nil error effectively 1802 01:14:09,480 --> 01:14:12,199 means no error so when we're looking at 1803 01:14:12,199 --> 01:14:13,960 this divide function we can understand 1804 01:14:13,960 --> 01:14:16,360 that if the divisor is zero we're going 1805 01:14:16,360 --> 01:14:18,719 to return early and and basically say we 1806 01:14:18,719 --> 01:14:20,159 can't do this division because we can't 1807 01:14:20,159 --> 01:14:22,719 divide by zero um otherwise we'll take 1808 01:14:22,719 --> 01:14:25,320 the happy path towards the end of the 1809 01:14:25,320 --> 01:14:28,480 function best practices when it comes to 1810 01:14:28,480 --> 01:14:30,080 software engineering and how we write 1811 01:14:30,080 --> 01:14:33,040 code change all the time right there's 1812 01:14:33,040 --> 01:14:34,360 millions of developers all around the 1813 01:14:34,360 --> 01:14:36,120 world writing code and we all have 1814 01:14:36,120 --> 01:14:39,120 different opinions and kind of the the 1815 01:14:39,120 --> 01:14:41,239 common opinion about a certain style 1816 01:14:41,239 --> 01:14:43,320 tends to change over time um the 1817 01:14:43,320 --> 01:14:45,000 interesting thing is I think that these 1818 01:14:45,000 --> 01:14:47,840 days um guard Clauses and early returns 1819 01:14:47,840 --> 01:14:49,719 are kind of looked at as a good thing um 1820 01:14:49,719 --> 01:14:51,600 this is clean code right this is a good 1821 01:14:51,600 --> 01:14:53,800 way to write code certainly most go 1822 01:14:53,800 --> 01:14:55,960 programmers think this way way um but it 1823 01:14:55,960 --> 01:14:58,080 wasn't always that way um there used to 1824 01:14:58,080 --> 01:15:00,719 kind of be a heuristic that uh 1825 01:15:00,719 --> 01:15:02,639 developers used which was you shouldn't 1826 01:15:02,639 --> 01:15:05,000 ever return from a function in more than 1827 01:15:05,000 --> 01:15:08,159 one place so back when that was kind of 1828 01:15:08,159 --> 01:15:09,480 the more popular way of doing things 1829 01:15:09,480 --> 01:15:12,960 you'd get kind of nasty if else nested 1830 01:15:12,960 --> 01:15:15,000 statements like this um if you look at 1831 01:15:15,000 --> 01:15:17,679 this function get insurance amount 1832 01:15:17,679 --> 01:15:20,040 basically takes a status as input it 1833 01:15:20,040 --> 01:15:23,440 returns an integer and it only has one 1834 01:15:23,440 --> 01:15:25,320 return statement so it only returns from 1835 01:15:25,320 --> 01:15:27,440 one place but I would argue that doesn't 1836 01:15:27,440 --> 01:15:29,320 necessarily make this function all that 1837 01:15:29,320 --> 01:15:31,480 much easier to understand right we're 1838 01:15:31,480 --> 01:15:33,400 initializing a variable up at the top 1839 01:15:33,400 --> 01:15:36,040 amount and then just in this big nasty 1840 01:15:36,040 --> 01:15:38,679 nested if else chain we're kind of 1841 01:15:38,679 --> 01:15:41,679 reassigning the value of amount uh based 1842 01:15:41,679 --> 01:15:44,320 on some conditional logic now compare 1843 01:15:44,320 --> 01:15:46,760 that with guard Clauses right so with 1844 01:15:46,760 --> 01:15:49,679 guard Clauses instead of overwriting the 1845 01:15:49,679 --> 01:15:51,480 variable amount and then returning it at 1846 01:15:51,480 --> 01:15:52,880 the end of the function we're just 1847 01:15:52,880 --> 01:15:55,480 returning early with the proper amount 1848 01:15:55,480 --> 01:15:57,159 at each step of the way now both of 1849 01:15:57,159 --> 01:15:59,280 these functions do the exact same thing 1850 01:15:59,280 --> 01:16:01,920 they have the same behavior um but I 1851 01:16:01,920 --> 01:16:03,960 would argue that the one with the guard 1852 01:16:03,960 --> 01:16:07,440 Clauses is much easier to understand so 1853 01:16:07,440 --> 01:16:09,440 the question for this exercise is which 1854 01:16:09,440 --> 01:16:12,760 is true guard Clauses are unreadable 1855 01:16:12,760 --> 01:16:14,760 guard Clauses are generally worse than 1856 01:16:14,760 --> 01:16:17,080 nested IFL statements or guard Clauses 1857 01:16:17,080 --> 01:16:20,560 provide a linear approach to logic trees 1858 01:16:20,560 --> 01:16:23,120 okay so it's definitely not um these two 1859 01:16:23,120 --> 01:16:24,480 right so I'm I'm going to go with 1860 01:16:24,480 --> 01:16:26,280 provide a linear approach to logic trees 1861 01:16:26,280 --> 01:16:28,760 and really all that means is rather than 1862 01:16:28,760 --> 01:16:30,560 having to follow kind of a tree 1863 01:16:30,560 --> 01:16:33,040 structure to look at conditional logic 1864 01:16:33,040 --> 01:16:35,080 we can just follow a straight line right 1865 01:16:35,080 --> 01:16:37,920 is it this no we move on is it this no 1866 01:16:37,920 --> 01:16:40,000 we can move on right it it allows us to 1867 01:16:40,000 --> 01:16:41,880 break up kind of the cognitive load when 1868 01:16:41,880 --> 01:16:43,760 we're when we're reading code so 1869 01:16:43,760 --> 01:16:46,639 definitely a linear approach there the 1870 01:16:46,639 --> 01:16:48,639 next question is what is a guard Clause 1871 01:16:48,639 --> 01:16:50,880 so a bit wise or operation an and 1872 01:16:50,880 --> 01:16:52,880 operation in Boolean logic or an early 1873 01:16:52,880 --> 01:16:54,080 return from a function when a given 1874 01:16:54,080 --> 01:16:56,840 condition is met and it is an early 1875 01:16:56,840 --> 01:16:59,560 return let's talk about structs so 1876 01:16:59,560 --> 01:17:01,280 structs are the first collection type 1877 01:17:01,280 --> 01:17:02,239 that we're going to talk about in this 1878 01:17:02,239 --> 01:17:04,480 course a collection type is just a type 1879 01:17:04,480 --> 01:17:07,480 that contains other types in the case of 1880 01:17:07,480 --> 01:17:09,600 a struct a struct is just a collection 1881 01:17:09,600 --> 01:17:11,719 of key value pairs if you're familiar 1882 01:17:11,719 --> 01:17:14,199 with python dictionaries or JavaScript 1883 01:17:14,199 --> 01:17:15,920 object literals this is basically the 1884 01:17:15,920 --> 01:17:19,000 same idea so for example we can define a 1885 01:17:19,000 --> 01:17:21,560 car struct and we can say a car has a 1886 01:17:21,560 --> 01:17:24,440 make a model a height and a width and 1887 01:17:24,440 --> 01:17:26,199 each of those feels has its own 1888 01:17:26,199 --> 01:17:28,679 Associated type so let's move on to the 1889 01:17:28,679 --> 01:17:30,199 assignment I think looking at the code 1890 01:17:30,199 --> 01:17:31,600 is going to be the easiest way to 1891 01:17:31,600 --> 01:17:34,440 understand structs okay complete the 1892 01:17:34,440 --> 01:17:36,400 message to send struct definition it 1893 01:17:36,400 --> 01:17:38,520 needs two Fields phone number an integer 1894 01:17:38,520 --> 01:17:41,760 and message a string and um on these 1895 01:17:41,760 --> 01:17:43,199 exercise I always recommend kind of 1896 01:17:43,199 --> 01:17:44,800 going and looking at the test weite this 1897 01:17:44,800 --> 01:17:46,600 is all the code the way boot Dev works 1898 01:17:46,600 --> 01:17:49,199 like all the code is here um and we're 1899 01:17:49,199 --> 01:17:50,840 really just testing standard output to 1900 01:17:50,840 --> 01:17:52,159 see if you got the right answer so you 1901 01:17:52,159 --> 01:17:54,159 can see literally everything that's 1902 01:17:54,159 --> 01:17:55,440 going on 1903 01:17:55,440 --> 01:17:57,560 um so here you can see where a message 1904 01:17:57,560 --> 01:17:59,320 to send is going to be instantiated with 1905 01:17:59,320 --> 01:18:00,960 phone numbers and messages and here you 1906 01:18:00,960 --> 01:18:04,520 can see where um it's the uh fields are 1907 01:18:04,520 --> 01:18:06,159 going to be accessed with the dot 1908 01:18:06,159 --> 01:18:07,880 operator so let me go ahead and run it 1909 01:18:07,880 --> 01:18:09,760 in its current state um we should get 1910 01:18:09,760 --> 01:18:11,719 yep a compile time error where it's 1911 01:18:11,719 --> 01:18:13,320 saying message is undefined phone number 1912 01:18:13,320 --> 01:18:15,600 is undefined right so we need to add 1913 01:18:15,600 --> 01:18:17,520 those to the 1914 01:18:17,520 --> 01:18:19,960 definition all right phone 1915 01:18:19,960 --> 01:18:22,600 number 1916 01:18:22,600 --> 01:18:26,280 integer message 1917 01:18:26,280 --> 01:18:28,679 string let's go ahead and run 1918 01:18:28,679 --> 01:18:31,280 that and sending message love to have 1919 01:18:31,280 --> 01:18:33,880 you aboard to that big number okay that 1920 01:18:33,880 --> 01:18:37,639 looks good to me struct keys can hold 1921 01:18:37,639 --> 01:18:40,400 any type uh not just primitive types 1922 01:18:40,400 --> 01:18:43,040 like integers strings and booleans um 1923 01:18:43,040 --> 01:18:45,199 here you can see we've actually nested 1924 01:18:45,199 --> 01:18:48,320 the wheel struct within the car struct 1925 01:18:48,320 --> 01:18:50,000 right so we have the car struct from the 1926 01:18:50,000 --> 01:18:51,520 last example and we've added a front 1927 01:18:51,520 --> 01:18:54,159 wheel and a back wheel and they are each 1928 01:18:54,159 --> 01:18:57,159 of type wheel right and a wheel has a 1929 01:18:57,159 --> 01:18:59,719 radius and a material so we can actually 1930 01:18:59,719 --> 01:19:02,120 Nest structs within other structs and 1931 01:19:02,120 --> 01:19:04,080 then we also saw this just a little bit 1932 01:19:04,080 --> 01:19:06,719 in the last assignment but this is how 1933 01:19:06,719 --> 01:19:09,280 we can instantiate a new instance of a 1934 01:19:09,280 --> 01:19:12,440 struct right so this is the struct 1935 01:19:12,440 --> 01:19:14,360 definition we're saying this is what a 1936 01:19:14,360 --> 01:19:16,600 car looks like and then here we've 1937 01:19:16,600 --> 01:19:20,320 created a new empty car called my car 1938 01:19:20,320 --> 01:19:22,040 and when you create it kind of with 1939 01:19:22,040 --> 01:19:26,280 those empty uh those empty brackets all 1940 01:19:26,280 --> 01:19:28,679 of the fields inside of the struct will 1941 01:19:28,679 --> 01:19:30,280 just be initialized to their default 1942 01:19:30,280 --> 01:19:32,679 values their zero values right so 1943 01:19:32,679 --> 01:19:34,840 strings will be empty strings ins will 1944 01:19:34,840 --> 01:19:37,880 be zero and then here we're using the 1945 01:19:37,880 --> 01:19:41,199 dot operator to access Fields right so 1946 01:19:41,199 --> 01:19:43,520 my car. front wheeel right so we're 1947 01:19:43,520 --> 01:19:45,600 accessing the front wheel key and then 1948 01:19:45,600 --> 01:19:48,000 radius to access access the radius 1949 01:19:48,000 --> 01:19:49,880 within the front wheel and we're setting 1950 01:19:49,880 --> 01:19:52,719 it equal to five again with this syntax 1951 01:19:52,719 --> 01:19:54,199 stuff it's just best to get Hands-On 1952 01:19:54,199 --> 01:19:56,560 keyboard and jump right into it so let's 1953 01:19:56,560 --> 01:19:58,440 get to the assignment says textio has a 1954 01:19:58,440 --> 01:20:00,280 bug we've been sending texts with 1955 01:20:00,280 --> 01:20:02,679 information missing before we send text 1956 01:20:02,679 --> 01:20:04,280 messages in texo we should check to make 1957 01:20:04,280 --> 01:20:06,960 sure the required Fields have nonzero 1958 01:20:06,960 --> 01:20:09,480 values notice that both the user struct 1959 01:20:09,480 --> 01:20:12,320 so that's this here is a nested struct 1960 01:20:12,320 --> 01:20:13,840 or notice that the user struct is a 1961 01:20:13,840 --> 01:20:15,560 nested struct within message to send 1962 01:20:15,560 --> 01:20:17,480 okay so message to send has a message 1963 01:20:17,480 --> 01:20:19,920 which is a string and then a sender and 1964 01:20:19,920 --> 01:20:22,400 a recipient and both of those are of 1965 01:20:22,400 --> 01:20:25,320 type user okay that makes sense a user 1966 01:20:25,320 --> 01:20:27,040 is the sender a user is the recipient 1967 01:20:27,040 --> 01:20:29,000 and then there is a message cool 1968 01:20:29,000 --> 01:20:31,880 complete the send the can send message 1969 01:20:31,880 --> 01:20:33,560 function 1970 01:20:33,560 --> 01:20:36,400 okay it should only return true if the 1971 01:20:36,400 --> 01:20:39,080 sender and recipient Fields each contain 1972 01:20:39,080 --> 01:20:41,800 a name and a number if any of the 1973 01:20:41,800 --> 01:20:43,880 default zero values are present return 1974 01:20:43,880 --> 01:20:47,360 false instead Okay cool so can send 1975 01:20:47,360 --> 01:20:48,600 message this is essentially a function 1976 01:20:48,600 --> 01:20:50,560 that's going to validate a message to 1977 01:20:50,560 --> 01:20:53,639 send to see if it actually has data 1978 01:20:53,639 --> 01:20:57,360 inside of it so so um if I run the code 1979 01:20:57,360 --> 01:21:00,920 right now it's always returning true 1980 01:21:00,920 --> 01:21:02,880 right so you have an appointment 1981 01:21:02,880 --> 01:21:05,120 tomorrow you have an event 1982 01:21:05,120 --> 01:21:08,600 tomorrow from Susie Saul ah see there's 1983 01:21:08,600 --> 01:21:10,080 a phone number missing there that's a 1984 01:21:10,080 --> 01:21:11,840 problem looks like there's a phone 1985 01:21:11,840 --> 01:21:14,199 number missing there that's a problem 1986 01:21:14,199 --> 01:21:18,800 okay let's see so sender and recipients 1987 01:21:18,800 --> 01:21:23,440 contain a name and a number so if M to 1988 01:21:23,440 --> 01:21:26,440 send 1989 01:21:27,560 --> 01:21:31,280 dot sender and recipi sender contain 1990 01:21:31,280 --> 01:21:34,159 name dot name 1991 01:21:34,159 --> 01:21:37,159 is 1992 01:21:37,360 --> 01:21:40,199 empty 1993 01:21:40,199 --> 01:21:41,880 false 1994 01:21:41,880 --> 01:21:46,159 right and then if m dot is going to be 1995 01:21:46,159 --> 01:21:48,639 recipient is empty also return FSE so 1996 01:21:48,639 --> 01:21:49,520 we're just going to do some guard 1997 01:21:49,520 --> 01:21:50,560 Clauses 1998 01:21:50,560 --> 01:21:52,920 here and then sender and recipient and 1999 01:21:52,920 --> 01:21:55,199 now we're interested in the number 2000 01:21:55,199 --> 01:21:58,719 number is an integer so if it's 2001 01:21:58,719 --> 01:22:00,639 zero cool so we're just we're just 2002 01:22:00,639 --> 01:22:02,719 basically doing a a very simple 2003 01:22:02,719 --> 01:22:05,320 validation to make sure um that names 2004 01:22:05,320 --> 01:22:07,679 aren't blank and numbers are not blank 2005 01:22:07,679 --> 01:22:10,400 so let me run 2006 01:22:11,040 --> 01:22:13,480 that okay so this one has all the 2007 01:22:13,480 --> 01:22:15,800 information there and it's sent now this 2008 01:22:15,800 --> 01:22:17,520 one has a number missing can't send 2009 01:22:17,520 --> 01:22:19,120 message that looks 2010 01:22:19,120 --> 01:22:22,880 correct okay this is looking good to 2011 01:22:22,880 --> 01:22:25,679 me all right next up we have Anonymous 2012 01:22:25,679 --> 01:22:28,920 strs so Anonymous strs are just struct 2013 01:22:28,920 --> 01:22:32,880 instances that don't have a name so 2014 01:22:32,880 --> 01:22:34,960 whenever you create a new Anonymous 2015 01:22:34,960 --> 01:22:37,920 struct in go you're you're immediately 2016 01:22:37,920 --> 01:22:40,880 instantiating a struct of a given type 2017 01:22:40,880 --> 01:22:42,960 right the type of the struct doesn't 2018 01:22:42,960 --> 01:22:45,320 have a name so for example here we have 2019 01:22:45,320 --> 01:22:46,159 a 2020 01:22:46,159 --> 01:22:49,520 struct with a make and a model now in 2021 01:22:49,520 --> 01:22:51,159 the exercise previous we remember we 2022 01:22:51,159 --> 01:22:53,800 actually had this same exact struct but 2023 01:22:53,800 --> 01:22:56,080 we'd given it name the name was car 2024 01:22:56,080 --> 01:22:58,239 right here we haven't created a new 2025 01:22:58,239 --> 01:23:00,040 struct definition we haven't created a 2026 01:23:00,040 --> 01:23:01,960 new struct definition called car instead 2027 01:23:01,960 --> 01:23:04,639 we're immediately instantiating a new 2028 01:23:04,639 --> 01:23:07,520 instance of a struct called my car this 2029 01:23:07,520 --> 01:23:09,920 could be named anything right and it 2030 01:23:09,920 --> 01:23:13,440 just has a make and a model field on it 2031 01:23:13,440 --> 01:23:15,600 so the only reason you would use an 2032 01:23:15,600 --> 01:23:18,239 anonymous struct is if you have no 2033 01:23:18,239 --> 01:23:22,159 reason to create more than one instance 2034 01:23:22,159 --> 01:23:24,840 of the struct so to be clear what's 2035 01:23:24,840 --> 01:23:26,120 happening here we're creating a new 2036 01:23:26,120 --> 01:23:28,600 variable called my car and it has two 2037 01:23:28,600 --> 01:23:30,760 Fields it's a struct with two Fields 2038 01:23:30,760 --> 01:23:33,360 make and model and we're immediately 2039 01:23:33,360 --> 01:23:38,920 giving it a value of make Tesla Model 3 2040 01:23:38,920 --> 01:23:41,600 and this type this specific struct type 2041 01:23:41,600 --> 01:23:42,960 doesn't exist anywhere else within our 2042 01:23:42,960 --> 01:23:44,719 program this is kind of a type that's 2043 01:23:44,719 --> 01:23:47,239 just unique to this one instance um 2044 01:23:47,239 --> 01:23:49,760 called my car it's not very common that 2045 01:23:49,760 --> 01:23:52,159 you'll see kind of top level um 2046 01:23:52,159 --> 01:23:54,520 Anonymous structs like this more often 2047 01:23:54,520 --> 01:23:57,440 you'll see nested Anonymous structs 2048 01:23:57,440 --> 01:24:00,120 right so rather than creating wheel as a 2049 01:24:00,120 --> 01:24:02,719 separate struct type we've just said 2050 01:24:02,719 --> 01:24:04,520 well Wheels kind of always exist within 2051 01:24:04,520 --> 01:24:06,760 cars I know that's not really true but 2052 01:24:06,760 --> 01:24:08,719 maybe within our program it's true um so 2053 01:24:08,719 --> 01:24:11,480 we just create a little Anonymous struct 2054 01:24:11,480 --> 01:24:14,639 um within the greater car struct now as 2055 01:24:14,639 --> 01:24:16,920 far as best practices in writing clean 2056 01:24:16,920 --> 01:24:19,320 code my opinion is that you should 2057 01:24:19,320 --> 01:24:22,600 generally favor um named structs you 2058 01:24:22,600 --> 01:24:23,960 avoid Anonymous structs unless you have 2059 01:24:23,960 --> 01:24:26,719 a really good reason to use them uh 2060 01:24:26,719 --> 01:24:29,040 you'll really never go wrong with naming 2061 01:24:29,040 --> 01:24:31,960 your structs okay so the question on 2062 01:24:31,960 --> 01:24:33,719 this assignment is what is a good reason 2063 01:24:33,719 --> 01:24:35,639 to use an anonymous struct you're 2064 01:24:35,639 --> 01:24:36,960 worried about security you need your 2065 01:24:36,960 --> 01:24:38,360 code to be faster you're worried about 2066 01:24:38,360 --> 01:24:41,600 user privacy or it is only being used 2067 01:24:41,600 --> 01:24:44,080 once well the only thing even remotely 2068 01:24:44,080 --> 01:24:46,520 related to how Anonymous trucks work um 2069 01:24:46,520 --> 01:24:48,480 is that it's only being used once so if 2070 01:24:48,480 --> 01:24:50,199 you're certain that you only want this 2071 01:24:50,199 --> 01:24:52,440 type to be used one time maybe you don't 2072 01:24:52,440 --> 01:24:54,800 want someone accidentally reusing a type 2073 01:24:54,800 --> 01:24:56,560 um then you might want to use an 2074 01:24:56,560 --> 01:24:57,520 anonymous 2075 01:24:57,520 --> 01:25:00,000 struct next question is what's one 2076 01:25:00,000 --> 01:25:02,360 advantage of using an anonymous struct 2077 01:25:02,360 --> 01:25:03,679 anonymous trucks make your code run 2078 01:25:03,679 --> 01:25:05,360 faster Anonymous strs prevent you from 2079 01:25:05,360 --> 01:25:07,159 reusing a struct definition you never 2080 01:25:07,159 --> 01:25:09,520 intended to reuse or Anonymous TRS can 2081 01:25:09,520 --> 01:25:12,320 be compiled more quickly um it's this 2082 01:25:12,320 --> 01:25:15,480 reuse one um one place that I have used 2083 01:25:15,480 --> 01:25:17,560 Anonymous kind of top level structs from 2084 01:25:17,560 --> 01:25:19,840 time to time is in HTTP handlers so if I 2085 01:25:19,840 --> 01:25:23,000 know that a given HTTP endpoint will 2086 01:25:23,000 --> 01:25:26,480 always return a a specific Json payload 2087 01:25:26,480 --> 01:25:28,560 then I'll use an anonymous struct to 2088 01:25:28,560 --> 01:25:31,639 define the shape of that Json payload we 2089 01:25:31,639 --> 01:25:33,560 haven't really talked about Json in go 2090 01:25:33,560 --> 01:25:35,840 yet but kind of spoiler alert structs 2091 01:25:35,840 --> 01:25:38,880 are how we structure Json data 2092 01:25:38,880 --> 01:25:42,000 typically next we have embedded structs 2093 01:25:42,000 --> 01:25:44,159 and embedded structs are not the same 2094 01:25:44,159 --> 01:25:47,159 thing as nested structs an embedded 2095 01:25:47,159 --> 01:25:48,800 struct is basically where would take all 2096 01:25:48,800 --> 01:25:51,679 the fields from one struct and kind of 2097 01:25:51,679 --> 01:25:54,480 shove them into another one uh let me 2098 01:25:54,480 --> 01:25:57,360 show you what I mean so here's our car 2099 01:25:57,360 --> 01:25:59,199 struct that we've been using for our 2100 01:25:59,199 --> 01:26:01,440 examples um it's got to make in a model 2101 01:26:01,440 --> 01:26:05,040 great here's our truck struct now you'll 2102 01:26:05,040 --> 01:26:09,320 notice we've embedded the car type here 2103 01:26:09,320 --> 01:26:12,840 but the car is missing kind of a name a 2104 01:26:12,840 --> 01:26:15,960 key in the truck struct bed size is the 2105 01:26:15,960 --> 01:26:18,280 key int is the type here we just have 2106 01:26:18,280 --> 01:26:21,360 the type which is car so what does this 2107 01:26:21,360 --> 01:26:22,960 do and how does it differ from a nested 2108 01:26:22,960 --> 01:26:25,880 struct well in the embedded struct if we 2109 01:26:25,880 --> 01:26:30,480 want to access the field model from a an 2110 01:26:30,480 --> 01:26:32,719 instance of a truck rather than doing 2111 01:26:32,719 --> 01:26:36,280 truck. car. model we would just do 2112 01:26:36,280 --> 01:26:39,880 truck. model because these fields of the 2113 01:26:39,880 --> 01:26:43,000 car type are becoming kind of top level 2114 01:26:43,000 --> 01:26:45,480 fields of the truck type we're 2115 01:26:45,480 --> 01:26:47,920 inheriting all of those fields from the 2116 01:26:47,920 --> 01:26:50,280 car type now I have to be careful with 2117 01:26:50,280 --> 01:26:52,119 the word inherit even though it is kind 2118 01:26:52,119 --> 01:26:53,920 of a pretty good descriptive term for 2119 01:26:53,920 --> 01:26:56,840 what's happening go is not an 2120 01:26:56,840 --> 01:26:58,880 objectoriented language because it 2121 01:26:58,880 --> 01:27:01,560 doesn't support classes or inheritance 2122 01:27:01,560 --> 01:27:03,520 in the class-based sense so if you're 2123 01:27:03,520 --> 01:27:04,840 familiar with the idea of 2124 01:27:04,840 --> 01:27:06,480 object-oriented programming just know 2125 01:27:06,480 --> 01:27:08,639 that classes and inheritance aren't 2126 01:27:08,639 --> 01:27:11,040 really what's going on here uh this is 2127 01:27:11,040 --> 01:27:12,320 you can almost just think of this as a 2128 01:27:12,320 --> 01:27:15,600 shorthand for kind of retyping this make 2129 01:27:15,600 --> 01:27:18,159 and model into the truck struct it's 2130 01:27:18,159 --> 01:27:20,920 it's almost just a syntactic sugar um so 2131 01:27:20,920 --> 01:27:23,760 that we don't have to retype all of 2132 01:27:23,760 --> 01:27:26,159 these Fields so let's take a look at 2133 01:27:26,159 --> 01:27:29,080 some code um and how we would use this 2134 01:27:29,080 --> 01:27:32,000 truck struct so I've created this new um 2135 01:27:32,000 --> 01:27:33,760 instance of a truck called it Lane's 2136 01:27:33,760 --> 01:27:36,280 truck has a bed size which is an integer 2137 01:27:36,280 --> 01:27:40,040 right and it has a car here now you 2138 01:27:40,040 --> 01:27:41,280 might look at that and say that looks an 2139 01:27:41,280 --> 01:27:43,920 awful lot like a nested struct and the 2140 01:27:43,920 --> 01:27:47,440 Syntax for creating a new instance of an 2141 01:27:47,440 --> 01:27:51,199 embedded struct is very similar to uh 2142 01:27:51,199 --> 01:27:53,199 the Syntax for a nested struct 2143 01:27:53,199 --> 01:27:54,639 essentially the key 2144 01:27:54,639 --> 01:27:57,639 is just the same name as the type this 2145 01:27:57,639 --> 01:28:00,840 just kind of a quirky thing about um 2146 01:28:00,840 --> 01:28:03,159 composite literals uh the embedded stuff 2147 01:28:03,159 --> 01:28:05,600 looks like the nested stuff however when 2148 01:28:05,600 --> 01:28:08,679 we are accessing the individual fields 2149 01:28:08,679 --> 01:28:12,560 on um Lanes truck using the dot operator 2150 01:28:12,560 --> 01:28:14,679 you'll see they're all accessed at the 2151 01:28:14,679 --> 01:28:18,040 top level it's not Lan truck uh doar 2152 01:28:18,040 --> 01:28:21,719 doake it's Lan truck. make right it's 2153 01:28:21,719 --> 01:28:23,719 not lanest truck. car. model it's just 2154 01:28:23,719 --> 01:28:26,119 LAN truck. model so those fields are 2155 01:28:26,119 --> 01:28:29,360 being brought up into the top level it's 2156 01:28:29,360 --> 01:28:31,199 just when we kind of instantiate the 2157 01:28:31,199 --> 01:28:33,159 truck the first time that we need to do 2158 01:28:33,159 --> 01:28:36,040 this sort of nested syntax so let's hop 2159 01:28:36,040 --> 01:28:38,560 into the assignment it says at texo a 2160 01:28:38,560 --> 01:28:41,000 user which is a struct represents an 2161 01:28:41,000 --> 01:28:43,280 account holder and a sender is just a 2162 01:28:43,280 --> 01:28:45,119 user with some additional sender 2163 01:28:45,119 --> 01:28:47,360 specific data a sender is a user that 2164 01:28:47,360 --> 01:28:49,000 has a rate limit field that tells us how 2165 01:28:49,000 --> 01:28:50,880 many messages they are allowed to send 2166 01:28:50,880 --> 01:28:52,520 fix the system by using an embedded 2167 01:28:52,520 --> 01:28:55,080 struct as expected by the Tex test code 2168 01:28:55,080 --> 01:28:56,119 okay so let's go ahead and take a look 2169 01:28:56,119 --> 01:28:57,560 at the test 2170 01:28:57,560 --> 01:28:59,880 code so it looks like the test code is 2171 01:28:59,880 --> 01:29:02,000 creating some 2172 01:29:02,000 --> 01:29:05,639 senders and it's expecting that a sender 2173 01:29:05,639 --> 01:29:08,760 has a rate limit and that it has a user 2174 01:29:08,760 --> 01:29:10,360 right and this is looking like an 2175 01:29:10,360 --> 01:29:11,280 embedded 2176 01:29:11,280 --> 01:29:14,639 struct and up here you can see s is a 2177 01:29:14,639 --> 01:29:17,080 sender and we're directly accessing name 2178 01:29:17,080 --> 01:29:19,400 number and rate limit all the top 2179 01:29:19,400 --> 01:29:22,000 level so I think all I need to do here 2180 01:29:22,000 --> 01:29:24,480 is embed the user structure in fact 2181 01:29:24,480 --> 01:29:26,679 let's run this without without that see 2182 01:29:26,679 --> 01:29:28,520 what happens yep we're getting some 2183 01:29:28,520 --> 01:29:29,760 undefined 2184 01:29:29,760 --> 01:29:34,400 Fields we'll embed the user type in 2185 01:29:34,400 --> 01:29:38,040 there and that's looking pretty good to 2186 01:29:38,040 --> 01:29:41,040 me I will mention just to give you an 2187 01:29:41,040 --> 01:29:42,440 idea of like when you use this in the 2188 01:29:42,440 --> 01:29:44,400 real world one place that I use it 2189 01:29:44,400 --> 01:29:47,040 actively on boot Dev is users have kind 2190 01:29:47,040 --> 01:29:49,440 of public fields on boot Dev and private 2191 01:29:49,440 --> 01:29:52,560 Fields so public fields are um stuff 2192 01:29:52,560 --> 01:29:54,159 that we show on the leaderboard things 2193 01:29:54,159 --> 01:29:55,800 that kind of anyone can see about your 2194 01:29:55,800 --> 01:29:57,800 profile maybe your bio or your profile 2195 01:29:57,800 --> 01:30:00,320 picture um but users also have private 2196 01:30:00,320 --> 01:30:03,119 Fields things like um your hashed 2197 01:30:03,119 --> 01:30:04,719 password right the password we store in 2198 01:30:04,719 --> 01:30:06,800 the database and I've actually 2199 01:30:06,800 --> 01:30:10,520 embedded the private Fields within the 2200 01:30:10,520 --> 01:30:13,719 public user so that I can easily nullify 2201 01:30:13,719 --> 01:30:16,239 them when I don't want to send private 2202 01:30:16,239 --> 01:30:19,719 data uh to a given web page all right 2203 01:30:19,719 --> 01:30:25,040 let's go ahead and run this code 2204 01:30:25,040 --> 01:30:27,360 let's talk about methods on structs or 2205 01:30:27,360 --> 01:30:30,440 just methods in general in go um I know 2206 01:30:30,440 --> 01:30:32,560 I told you go is not object oriented and 2207 01:30:32,560 --> 01:30:35,199 it's not but if you squint really hard 2208 01:30:35,199 --> 01:30:38,480 structs in go kind of look like classes 2209 01:30:38,480 --> 01:30:41,360 in a language like Java JavaScript or 2210 01:30:41,360 --> 01:30:44,199 python so methods in go are just 2211 01:30:44,199 --> 01:30:46,920 Behavior or functions that we can Define 2212 01:30:46,920 --> 01:30:49,199 on a type and more often than not we end 2213 01:30:49,199 --> 01:30:51,400 up defining methods on structs although 2214 01:30:51,400 --> 01:30:54,080 we could Define methods on any type so 2215 01:30:54,080 --> 01:30:56,440 let's take a look at the Syntax for this 2216 01:30:56,440 --> 01:30:58,199 so here we have a simple rectangle 2217 01:30:58,199 --> 01:31:01,400 struct it has a width and a height right 2218 01:31:01,400 --> 01:31:04,840 and here we've defined an area method on 2219 01:31:04,840 --> 01:31:07,840 the rectangle struct so this is just a 2220 01:31:07,840 --> 01:31:09,480 function right we're familiar with 2221 01:31:09,480 --> 01:31:11,560 functions already the only difference is 2222 01:31:11,560 --> 01:31:13,560 that we've added this special parameter 2223 01:31:13,560 --> 01:31:16,719 before the name of the function which is 2224 01:31:16,719 --> 01:31:18,520 again just a parameter that comes into 2225 01:31:18,520 --> 01:31:20,560 the function just it's just a special 2226 01:31:20,560 --> 01:31:23,520 parameter um and in this case it is of 2227 01:31:23,520 --> 01:31:25,719 type rect which is just a struct and 2228 01:31:25,719 --> 01:31:28,520 we've named it R and then this function 2229 01:31:28,520 --> 01:31:31,880 just returns r. width * r. height right 2230 01:31:31,880 --> 01:31:34,840 so it Returns the area of the rectangle 2231 01:31:34,840 --> 01:31:38,080 so why would we use a method on a struct 2232 01:31:38,080 --> 01:31:39,960 well there are reasons that we'll get to 2233 01:31:39,960 --> 01:31:42,280 later when we talk about interfaces um 2234 01:31:42,280 --> 01:31:44,440 but for now it's mostly a syntactic 2235 01:31:44,440 --> 01:31:47,239 thing a syntactic sugar thing if we have 2236 01:31:47,239 --> 01:31:49,600 behavior that we want to Define on a 2237 01:31:49,600 --> 01:31:52,199 given type then strs can be a really 2238 01:31:52,199 --> 01:31:53,960 good choice they give us this nice 2239 01:31:53,960 --> 01:31:55,280 tactic sugar right we create this new 2240 01:31:55,280 --> 01:31:57,600 rectangle called R and now we can just 2241 01:31:57,600 --> 01:32:00,760 call r. area to get the area of the 2242 01:32:00,760 --> 01:32:03,480 rectangle it's kind of a nice way to do 2243 01:32:03,480 --> 01:32:06,639 computed properties on a type right so 2244 01:32:06,639 --> 01:32:09,520 we could have stored area as a separate 2245 01:32:09,520 --> 01:32:12,760 number within the wct struct the problem 2246 01:32:12,760 --> 01:32:15,199 with that is now we lose kind of a 2247 01:32:15,199 --> 01:32:17,199 single source of Truth when it comes to 2248 01:32:17,199 --> 01:32:19,880 the area right if we store the area as 2249 01:32:19,880 --> 01:32:22,960 say 50 and the width and height as 5 and 2250 01:32:22,960 --> 01:32:25,320 10 but then we update the height and 2251 01:32:25,320 --> 01:32:27,560 forget to update the area right now we 2252 01:32:27,560 --> 01:32:29,560 have a bug in our code so this is a 2253 01:32:29,560 --> 01:32:33,480 great way to kind of have a oneline 2254 01:32:33,480 --> 01:32:36,239 accessor to get the area of a rectangle 2255 01:32:36,239 --> 01:32:37,960 but we don't have to actually store that 2256 01:32:37,960 --> 01:32:40,679 area in our struct as kind of duplicate 2257 01:32:40,679 --> 01:32:43,040 data so let's get down to the assignment 2258 01:32:43,040 --> 01:32:45,440 says let's clean up texo authentication 2259 01:32:45,440 --> 01:32:47,760 logic we store our users authentication 2260 01:32:47,760 --> 01:32:49,880 data inside an authentication info 2261 01:32:49,880 --> 01:32:51,639 struct okay so that's here it's got a 2262 01:32:51,639 --> 01:32:53,679 username and a password we need a method 2263 01:32:53,679 --> 01:32:55,360 that can take that data and return a 2264 01:32:55,360 --> 01:32:57,679 basic authorization string the format of 2265 01:32:57,679 --> 01:32:59,679 the string should be authorization basic 2266 01:32:59,679 --> 01:33:01,719 username colon password right so this is 2267 01:33:01,719 --> 01:33:03,840 the kind of standard basic authorization 2268 01:33:03,840 --> 01:33:06,280 that's used in HTTP requests the 2269 01:33:06,280 --> 01:33:07,719 assignment says create a method on 2270 01:33:07,719 --> 01:33:10,520 authentication info called get basic off 2271 01:33:10,520 --> 01:33:13,360 that Returns the formatted string Okay 2272 01:33:13,360 --> 01:33:18,080 cool so let's create a 2273 01:33:18,080 --> 01:33:20,880 new a new method and we can kind of 2274 01:33:20,880 --> 01:33:23,360 reference this syntax over here so it's 2275 01:33:23,360 --> 01:33:26,199 funk and we want the receiver to be an 2276 01:33:26,199 --> 01:33:27,719 authentication info struct so I'll just 2277 01:33:27,719 --> 01:33:29,520 call it AI oh that's that's actually 2278 01:33:29,520 --> 01:33:33,480 confusing let's do off aui 2279 01:33:33,480 --> 01:33:36,080 authentication 2280 01:33:36,080 --> 01:33:39,600 info and we wanted the name of the 2281 01:33:39,600 --> 01:33:41,639 method to be called get basic 2282 01:33:41,639 --> 01:33:45,199 off and it returns a 2283 01:33:45,199 --> 01:33:49,280 string okay and then we want to return 2284 01:33:49,280 --> 01:33:51,199 this format 2285 01:33:51,199 --> 01:33:54,360 here so if you remember we can use the 2286 01:33:54,360 --> 01:33:56,159 format package to do that so we'll 2287 01:33:56,159 --> 01:33:59,360 return fmts 2288 01:33:59,360 --> 01:34:02,119 printf remember s printf Returns the 2289 01:34:02,119 --> 01:34:03,400 string rather than printing it to 2290 01:34:03,400 --> 01:34:08,639 standard out or to the console and we'll 2291 01:34:09,199 --> 01:34:11,760 use that 2292 01:34:11,760 --> 01:34:14,600 template username and password are both 2293 01:34:14,600 --> 01:34:17,119 just strings so we'll use percent s for 2294 01:34:17,119 --> 01:34:19,760 our formatting verbs and then we can do 2295 01:34:19,760 --> 01:34:24,480 off I dot username first 2296 01:34:24,480 --> 01:34:27,520 and ai. 2297 01:34:27,520 --> 01:34:30,239 password next okay cool that looks 2298 01:34:30,239 --> 01:34:34,480 correct to me let's run 2299 01:34:35,080 --> 01:34:39,040 it perfect let's talk about interfaces 2300 01:34:39,040 --> 01:34:40,800 so an interface in go is just a 2301 01:34:40,800 --> 01:34:43,840 collection of method signatures for 2302 01:34:43,840 --> 01:34:45,520 example take a look at this shape 2303 01:34:45,520 --> 01:34:47,320 interface so we have an interface it's 2304 01:34:47,320 --> 01:34:50,000 named shape and it specifies two 2305 01:34:50,000 --> 01:34:52,360 different method signatures so area is a 2306 01:34:52,360 --> 01:34:55,679 method that takes no parameters and 2307 01:34:55,679 --> 01:34:58,239 returns a float 64 perimeter is another 2308 01:34:58,239 --> 01:34:59,880 method that takes no parameters and 2309 01:34:59,880 --> 01:35:02,920 returns a float 64 now any type that 2310 01:35:02,920 --> 01:35:05,800 implements both of these methods and and 2311 01:35:05,800 --> 01:35:08,480 matches their method signatures will 2312 01:35:08,480 --> 01:35:10,480 implement the shape interface which 2313 01:35:10,480 --> 01:35:11,760 really just means that we can think of 2314 01:35:11,760 --> 01:35:14,560 it and treat it as a shape so for 2315 01:35:14,560 --> 01:35:16,000 example let's take a look at this 2316 01:35:16,000 --> 01:35:19,880 rectangle struct so erect has a width 2317 01:35:19,880 --> 01:35:22,000 and a height uh both of which are float 2318 01:35:22,000 --> 01:35:24,520 64s and again this is just a this is 2319 01:35:24,520 --> 01:35:27,719 just a kind of standard struct and it 2320 01:35:27,719 --> 01:35:31,119 has two methods on it uh one is the area 2321 01:35:31,119 --> 01:35:32,760 method that takes no parameters returns 2322 01:35:32,760 --> 01:35:35,239 a float 64 um one is the perimeter that 2323 01:35:35,239 --> 01:35:37,600 takes no parameters and returns a float 2324 01:35:37,600 --> 01:35:40,320 64 and because a rectangle implements 2325 01:35:40,320 --> 01:35:42,600 both of these methods we can think of a 2326 01:35:42,600 --> 01:35:46,159 rectangle as a shape a shape is just 2327 01:35:46,159 --> 01:35:48,520 anything where we can kind of calculate 2328 01:35:48,520 --> 01:35:51,239 its area and calculate its perimeter and 2329 01:35:51,239 --> 01:35:53,320 multiple types can implement the same 2330 01:35:53,320 --> 01:35:54,159 interface 2331 01:35:54,159 --> 01:35:58,040 so for example this circle struct it has 2332 01:35:58,040 --> 01:35:59,800 different underlying data right rather 2333 01:35:59,800 --> 01:36:01,119 than a width and a height we can 2334 01:36:01,119 --> 01:36:03,960 represent a circle with just a radius um 2335 01:36:03,960 --> 01:36:05,360 but to calculate its area and its 2336 01:36:05,360 --> 01:36:07,440 perimeter the calculation is a little 2337 01:36:07,440 --> 01:36:09,199 bit different right we're using pi for 2338 01:36:09,199 --> 01:36:11,880 example um but the method signature is 2339 01:36:11,880 --> 01:36:13,600 identical right we don't pass anything 2340 01:36:13,600 --> 01:36:15,159 in because we have all the data we need 2341 01:36:15,159 --> 01:36:17,520 on the circle struct and we just return 2342 01:36:17,520 --> 01:36:20,440 a float 64 so both circles and 2343 01:36:20,440 --> 01:36:23,159 rectangles because they implement the 2344 01:36:23,159 --> 01:36:25,679 required methods can be thought of as 2345 01:36:25,679 --> 01:36:27,800 shapes or we could say they implement 2346 01:36:27,800 --> 01:36:30,159 the shape interface let's get into the 2347 01:36:30,159 --> 01:36:31,480 assignment I think it'll all start to 2348 01:36:31,480 --> 01:36:32,880 make a little more sense so the 2349 01:36:32,880 --> 01:36:34,719 assignment says the birthday message and 2350 01:36:34,719 --> 01:36:36,400 sending report strs have already 2351 01:36:36,400 --> 01:36:39,800 implemented the get message method so 2352 01:36:39,800 --> 01:36:42,080 let's take a look at that so uh birthday 2353 01:36:42,080 --> 01:36:44,360 message is this struct here sending 2354 01:36:44,360 --> 01:36:45,760 report is this struct here they both 2355 01:36:45,760 --> 01:36:48,199 have this get message method that 2356 01:36:48,199 --> 01:36:51,000 returns a string and they're just it 2357 01:36:51,000 --> 01:36:52,400 looks like the strings that they return 2358 01:36:52,400 --> 01:36:53,360 are just a little bit different right 2359 01:36:53,360 --> 01:36:56,000 the birthday messages get message uh 2360 01:36:56,000 --> 01:36:58,800 function returns this like hi blank it 2361 01:36:58,800 --> 01:37:01,239 is your birthday on blank and a sending 2362 01:37:01,239 --> 01:37:04,040 report says your blank report is ready 2363 01:37:04,040 --> 01:37:05,440 right so they just they just format a 2364 01:37:05,440 --> 01:37:06,639 little little 2365 01:37:06,639 --> 01:37:09,000 differently okay so assignment says 2366 01:37:09,000 --> 01:37:11,159 first add the get message method as a 2367 01:37:11,159 --> 01:37:14,040 requirement on the method interface okay 2368 01:37:14,040 --> 01:37:16,679 so we need to finish the message 2369 01:37:16,679 --> 01:37:20,600 interface and add a get message 2370 01:37:20,600 --> 01:37:24,159 method that returns a string 2371 01:37:24,159 --> 01:37:27,600 Okay cool so now this message interface 2372 01:37:27,600 --> 01:37:30,159 because birthday message and sending 2373 01:37:30,159 --> 01:37:33,840 report both implement this method we can 2374 01:37:33,840 --> 01:37:37,400 think of both of those as messages next 2375 01:37:37,400 --> 01:37:39,880 it says complete the send message 2376 01:37:39,880 --> 01:37:41,960 function it should print a messages 2377 01:37:41,960 --> 01:37:43,360 message which it obtains through the 2378 01:37:43,360 --> 01:37:46,440 interface meth method Okay cool so the a 2379 01:37:46,440 --> 01:37:49,760 message is an interface so inside of the 2380 01:37:49,760 --> 01:37:51,639 send message function we don't actually 2381 01:37:51,639 --> 01:37:53,639 know if we're dealing with say a 2382 01:37:53,639 --> 01:37:55,719 birthday message or a sending report we 2383 01:37:55,719 --> 01:37:57,119 just know that we have access to a 2384 01:37:57,119 --> 01:37:58,599 message so really the only thing we can 2385 01:37:58,599 --> 01:38:02,599 do with it is call get message which we 2386 01:38:02,599 --> 01:38:04,840 know will return a string and it says it 2387 01:38:04,840 --> 01:38:08,000 should print a message so we'll do ft. 2388 01:38:08,000 --> 01:38:12,520 print line just print out the message 2389 01:38:12,520 --> 01:38:15,440 cool okay now this is powerful right 2390 01:38:15,440 --> 01:38:17,920 let's go take a look at how this code is 2391 01:38:17,920 --> 01:38:19,960 actually called so we have this test 2392 01:38:19,960 --> 01:38:22,119 function that also just takes a method a 2393 01:38:22,119 --> 01:38:24,119 message and it 2394 01:38:24,119 --> 01:38:25,440 sends that message right it's just 2395 01:38:25,440 --> 01:38:28,000 calling our send message function 2396 01:38:28,000 --> 01:38:30,520 here but down here and this is where 2397 01:38:30,520 --> 01:38:33,560 it's most interesting the test function 2398 01:38:33,560 --> 01:38:37,760 is not past like interface literals 2399 01:38:37,760 --> 01:38:39,800 that's not even like a real thing right 2400 01:38:39,800 --> 01:38:41,719 an interface is like abstract type that 2401 01:38:41,719 --> 01:38:44,679 represents other types instead because 2402 01:38:44,679 --> 01:38:47,560 the test function takes an interface we 2403 01:38:47,560 --> 01:38:49,760 can pass into it any struct that 2404 01:38:49,760 --> 01:38:52,480 implements that interface so for example 2405 01:38:52,480 --> 01:38:54,360 here on line 42 we're passing in a 2406 01:38:54,360 --> 01:38:56,719 sending report and then on line 46 we're 2407 01:38:56,719 --> 01:38:58,520 passing in a birthday message those are 2408 01:38:58,520 --> 01:39:00,880 two different types in a strongly typed 2409 01:39:00,880 --> 01:39:02,800 language being passed in as the first 2410 01:39:02,800 --> 01:39:04,960 parameter to a single function but the 2411 01:39:04,960 --> 01:39:08,599 reason it works is because we're using 2412 01:39:08,599 --> 01:39:10,520 interfaces okay let's go ahead and run 2413 01:39:10,520 --> 01:39:13,360 this see what 2414 01:39:13,520 --> 01:39:15,719 happens your first report report is 2415 01:39:15,719 --> 01:39:17,760 ready you've sent 10 messages hi Dondo 2416 01:39:17,760 --> 01:39:19,320 it is your 2417 01:39:19,320 --> 01:39:22,760 birthday this looks great this looks 2418 01:39:22,760 --> 01:39:25,040 great to me 2419 01:39:25,040 --> 01:39:28,119 in go interfaces are implemented 2420 01:39:28,119 --> 01:39:30,199 implicitly and what that means is when 2421 01:39:30,199 --> 01:39:32,360 we have a type like in our last example 2422 01:39:32,360 --> 01:39:34,040 we had the rectangle type that 2423 01:39:34,040 --> 01:39:36,760 implemented the shape interface we never 2424 01:39:36,760 --> 01:39:40,199 had to explicitly write anywhere on the 2425 01:39:40,199 --> 01:39:44,159 rectangle struct that it was intended to 2426 01:39:44,159 --> 01:39:47,360 implement the shape interface because it 2427 01:39:47,360 --> 01:39:49,000 satisfied all the requirements of the 2428 01:39:49,000 --> 01:39:50,880 shape interface it just kind of 2429 01:39:50,880 --> 01:39:53,440 automatically implemented it and that's 2430 01:39:53,440 --> 01:39:55,520 fairly unique to go in a language like 2431 01:39:55,520 --> 01:39:56,760 Java we might have to write something 2432 01:39:56,760 --> 01:39:58,560 like this um we could take a look at 2433 01:39:58,560 --> 01:40:00,400 this little example here we've got this 2434 01:40:00,400 --> 01:40:02,480 employee interface and a contractor 2435 01:40:02,480 --> 01:40:05,040 struct if we wanted the contractor to 2436 01:40:05,040 --> 01:40:07,280 implement the employee we would need it 2437 01:40:07,280 --> 01:40:09,360 to still fulfill the interface right by 2438 01:40:09,360 --> 01:40:10,440 implementing all the methods but we 2439 01:40:10,440 --> 01:40:12,400 might need to also explicitly type 2440 01:40:12,400 --> 01:40:13,960 something like 2441 01:40:13,960 --> 01:40:15,520 implements 2442 01:40:15,520 --> 01:40:18,480 employee right we explicitly say that we 2443 01:40:18,480 --> 01:40:21,000 intend to implement that interface in go 2444 01:40:21,000 --> 01:40:23,040 it's done automatically let's hop into 2445 01:40:23,040 --> 01:40:25,040 the ass assignment it says at texo we 2446 01:40:25,040 --> 01:40:26,920 have full-time employees and contract 2447 01:40:26,920 --> 01:40:28,599 employees we've been tasked with making 2448 01:40:28,599 --> 01:40:31,400 a more General employee interface so 2449 01:40:31,400 --> 01:40:32,920 that dealing with different employee 2450 01:40:32,920 --> 01:40:35,360 types is a little simpler add the 2451 01:40:35,360 --> 01:40:37,440 missing get salary method to the 2452 01:40:37,440 --> 01:40:39,760 contractor type so that it fulfills the 2453 01:40:39,760 --> 01:40:42,560 employee interface Okay cool so we have 2454 01:40:42,560 --> 01:40:44,080 the employee interface we have the 2455 01:40:44,080 --> 01:40:45,599 contractor 2456 01:40:45,599 --> 01:40:47,440 struct um and if we look at the 2457 01:40:47,440 --> 01:40:48,800 full-time struct it looks like it 2458 01:40:48,800 --> 01:40:49,880 already 2459 01:40:49,880 --> 01:40:53,119 implements the employee interface so we 2460 01:40:53,119 --> 01:40:56,119 just need to add the Missing Method 2461 01:40:56,119 --> 01:40:58,960 because right now a contractor has a get 2462 01:40:58,960 --> 01:41:01,080 name but does not have a get salary Okay 2463 01:41:01,080 --> 01:41:03,239 cool so let's go ahead and do that we'll 2464 01:41:03,239 --> 01:41:04,800 do 2465 01:41:04,800 --> 01:41:07,960 employee get salary it returns an 2466 01:41:07,960 --> 01:41:11,199 INT and a contractor's salary is their 2467 01:41:11,199 --> 01:41:13,719 hourly pay multiplied by how many hours 2468 01:41:13,719 --> 01:41:18,679 they work per year okay so be something 2469 01:41:18,679 --> 01:41:20,679 like 2470 01:41:20,679 --> 01:41:27,679 c. hourly pay multiplied by c. hours 2471 01:41:27,679 --> 01:41:29,639 per 2472 01:41:29,639 --> 01:41:32,400 year okay and just because I'm curious I 2473 01:41:32,400 --> 01:41:33,880 want to go look at how a full-time 2474 01:41:33,880 --> 01:41:37,159 salary uh employee works yeah so you can 2475 01:41:37,159 --> 01:41:39,840 see the the way that a full-time 2476 01:41:39,840 --> 01:41:42,280 employee their salary is calculated is 2477 01:41:42,280 --> 01:41:43,679 is totally different like their their 2478 01:41:43,679 --> 01:41:45,719 salary is actually just stored probably 2479 01:41:45,719 --> 01:41:46,840 because the way we think of full-time 2480 01:41:46,840 --> 01:41:48,000 employees is like you know you make 2481 01:41:48,000 --> 01:41:50,520 $60,000 a year you make $70,000 a year 2482 01:41:50,520 --> 01:41:52,760 whereas contractors often get paid by 2483 01:41:52,760 --> 01:41:54,119 the hour so it make sense that they have 2484 01:41:54,119 --> 01:41:56,960 a different calculation um and then down 2485 01:41:56,960 --> 01:41:59,320 here in the test Suite um this looks 2486 01:41:59,320 --> 01:42:00,920 very similar to the last assignment 2487 01:42:00,920 --> 01:42:03,599 where the test function is able to take 2488 01:42:03,599 --> 01:42:06,480 as inputs any type of employee right so 2489 01:42:06,480 --> 01:42:08,080 we can pass in both full-time and 2490 01:42:08,080 --> 01:42:09,840 contractors here uh let's go ahead and 2491 01:42:09,840 --> 01:42:12,080 run 2492 01:42:13,719 --> 01:42:17,199 that Jack Bob and Jill we can see all of 2493 01:42:17,199 --> 01:42:21,159 their salaries even 2494 01:42:21,239 --> 01:42:24,119 though Jack is full-time and Bob and 2495 01:42:24,119 --> 01:42:26,320 Jill are both contractors so that looks 2496 01:42:26,320 --> 01:42:29,920 good to me in go types Implement 2497 01:42:29,920 --> 01:42:31,840 interfaces implicitly because it kind of 2498 01:42:31,840 --> 01:42:33,560 decouples the definition of the 2499 01:42:33,560 --> 01:42:35,679 interface from the definition of the 2500 01:42:35,679 --> 01:42:37,480 type the type doesn't even really need 2501 01:42:37,480 --> 01:42:40,199 to know that it implements a certain 2502 01:42:40,199 --> 01:42:42,960 interface and that's really really cool 2503 01:42:42,960 --> 01:42:45,080 because it means it's easy for a type to 2504 01:42:45,080 --> 01:42:47,760 inter to implement lots of different 2505 01:42:47,760 --> 01:42:50,199 interfaces so the quiz question here is 2506 01:42:50,199 --> 01:42:52,719 how is an interface fulfilled answers 2507 01:42:52,719 --> 01:42:55,119 are type has all the required interfaces 2508 01:42:55,119 --> 01:42:58,360 methods defined on it or a struct embeds 2509 01:42:58,360 --> 01:43:00,800 the interface in its definition and the 2510 01:43:00,800 --> 01:43:02,560 answer is going to be it has all the 2511 01:43:02,560 --> 01:43:05,040 methods defined the next question is can 2512 01:43:05,040 --> 01:43:08,119 a Type fulfill multiple interfaces or 2513 01:43:08,119 --> 01:43:11,119 Implement multiple interfaces and yes 2514 01:43:11,119 --> 01:43:13,800 why not another quiz question go uses 2515 01:43:13,800 --> 01:43:16,199 the blank keyword to show that a type 2516 01:43:16,199 --> 01:43:18,480 implements an interface and the answers 2517 01:43:18,480 --> 01:43:20,400 are fulfills implements inherits and 2518 01:43:20,400 --> 01:43:22,719 there is no keyword in go and the answer 2519 01:43:22,719 --> 01:43:24,760 is that there there is no keyword in go 2520 01:43:24,760 --> 01:43:28,280 interfaces are implemented 2521 01:43:31,280 --> 01:43:33,639 implicitly in the next question it says 2522 01:43:33,639 --> 01:43:36,280 in the example given the blank type 2523 01:43:36,280 --> 01:43:38,679 implements the blank interface let's 2524 01:43:38,679 --> 01:43:41,800 take a look so example here we've got 2525 01:43:41,800 --> 01:43:45,199 the shape interface circle 2526 01:43:45,199 --> 01:43:48,040 struct circle has an area method so it 2527 01:43:48,040 --> 01:43:50,560 looks like the circle type implements 2528 01:43:50,560 --> 01:43:52,800 the shape interface like we talked about 2529 01:43:52,800 --> 01:43:55,239 before or a type can Implement multiple 2530 01:43:55,239 --> 01:43:57,119 interfaces it just needs to have all the 2531 01:43:57,119 --> 01:43:58,440 methods for all of the different 2532 01:43:58,440 --> 01:44:00,639 interfaces for example the empty 2533 01:44:00,639 --> 01:44:02,960 interface so that's this this definition 2534 01:44:02,960 --> 01:44:05,520 right here this is an interface with no 2535 01:44:05,520 --> 01:44:08,639 methods required is actually always 2536 01:44:08,639 --> 01:44:11,560 implemented by every single type in the 2537 01:44:11,560 --> 01:44:13,679 go programming language now it's often 2538 01:44:13,679 --> 01:44:15,760 not a very useful interface because you 2539 01:44:15,760 --> 01:44:17,480 can't really do anything with an empty 2540 01:44:17,480 --> 01:44:19,880 interface you have no methods to call 2541 01:44:19,880 --> 01:44:21,880 let's jump down into the assignment it 2542 01:44:21,880 --> 01:44:23,719 says add the required methods the email 2543 01:44:23,719 --> 01:44:25,920 typee implements both the expense and 2544 01:44:25,920 --> 01:44:28,040 printer interfaces Okay cool so we got 2545 01:44:28,040 --> 01:44:31,320 these expense and printer interfaces two 2546 01:44:31,320 --> 01:44:33,520 different methods we need to implement 2547 01:44:33,520 --> 01:44:35,480 and we have this email type with an is 2548 01:44:35,480 --> 01:44:39,520 subscribed Boolean and body string cool 2549 01:44:39,520 --> 01:44:40,800 all right cost 2550 01:44:40,800 --> 01:44:43,760 method if the email is not subscribed so 2551 01:44:43,760 --> 01:44:47,440 if not e do is subscribed I believe is 2552 01:44:47,440 --> 01:44:51,080 what the field was then the cost is 2553 01:44:51,080 --> 01:44:54,320 0.05 times 2554 01:44:54,320 --> 01:44:57,760 uh the length for each character in the 2555 01:44:57,760 --> 01:45:01,560 body so the length e do body now 2556 01:45:01,560 --> 01:45:03,960 remember go is strongly typed and we 2557 01:45:03,960 --> 01:45:06,320 can't multiply an INT by a float 2558 01:45:06,320 --> 01:45:08,760 directly so we need to cast this integer 2559 01:45:08,760 --> 01:45:11,560 sorry I think I highlighted those 2560 01:45:11,560 --> 01:45:13,639 backwards the length of the body is an 2561 01:45:13,639 --> 01:45:16,199 integer this is a float so we need to 2562 01:45:16,199 --> 01:45:18,520 cast the length of the body to a float 2563 01:45:18,520 --> 01:45:20,960 so we can we can multiply a float by a 2564 01:45:20,960 --> 01:45:24,159 float um otherwise we'll 2565 01:45:24,159 --> 01:45:27,760 turn uh it's 2566 01:45:28,440 --> 01:45:31,560 0.01 times that same thing the length of 2567 01:45:31,560 --> 01:45:34,639 the body cool uh the print function 2568 01:45:34,639 --> 01:45:35,920 should just print to standard out the 2569 01:45:35,920 --> 01:45:39,560 emails body text easy enough fm. 2570 01:45:39,560 --> 01:45:42,880 printline e. 2571 01:45:42,880 --> 01:45:47,159 body okay so now our email struct 2572 01:45:47,159 --> 01:45:49,639 implements both of these interfaces and 2573 01:45:49,639 --> 01:45:54,400 if we come down here to look at the test 2574 01:45:54,400 --> 01:45:56,599 function this is interesting the test 2575 01:45:56,599 --> 01:45:59,520 function takes an expense and a 2576 01:45:59,520 --> 01:46:01,560 printer right so we can use both of 2577 01:46:01,560 --> 01:46:03,119 those uh methods 2578 01:46:03,119 --> 01:46:07,480 there and actually the email struct so 2579 01:46:07,480 --> 01:46:09,760 we're creating instances of emails here 2580 01:46:09,760 --> 01:46:12,440 we're actually passing it into test as 2581 01:46:12,440 --> 01:46:15,480 both the expense and the printer right 2582 01:46:15,480 --> 01:46:17,080 because it makes sense it implements 2583 01:46:17,080 --> 01:46:19,520 both cool let me run 2584 01:46:19,520 --> 01:46:23,080 that oh what did I screw up 05 time FL 6 2585 01:46:23,080 --> 01:46:27,800 4 length value of type float 64 is not 2586 01:46:28,040 --> 01:46:30,760 used let's 2587 01:46:30,760 --> 01:46:36,719 see 0.05 time float 64 length of e body 2588 01:46:36,719 --> 01:46:39,119 what did I screw up value of type float 2589 01:46:39,119 --> 01:46:42,239 64 is not 2590 01:46:42,280 --> 01:46:45,760 used I forgot my return cool let's try 2591 01:46:45,760 --> 01:46:47,960 that 2592 01:46:49,360 --> 01:46:51,840 again okay 2593 01:46:51,840 --> 01:46:54,840 so printing with cost 11 cents hello 2594 01:46:54,840 --> 01:46:56,920 there printing with cost $1 I want my 2595 01:46:56,920 --> 01:46:58,920 money back yeah that looks that looks 2596 01:46:58,920 --> 01:47:01,760 pretty good let's submit 2597 01:47:01,760 --> 01:47:03,960 it up until this point we haven't really 2598 01:47:03,960 --> 01:47:06,480 been naming the arguments of our 2599 01:47:06,480 --> 01:47:09,280 interfaces method signatures um but we 2600 01:47:09,280 --> 01:47:11,119 totally could so if we take a look at 2601 01:47:11,119 --> 01:47:14,360 this this is The copier interface it's a 2602 01:47:14,360 --> 01:47:16,239 uh copy method that it requires which 2603 01:47:16,239 --> 01:47:19,000 takes two strings and returns an INT um 2604 01:47:19,000 --> 01:47:20,360 the interesting thing is when you look 2605 01:47:20,360 --> 01:47:22,360 at this method signature it's kind of 2606 01:47:22,360 --> 01:47:25,159 hard to tell what the intention behind 2607 01:47:25,159 --> 01:47:26,920 the interface is it's like great it 2608 01:47:26,920 --> 01:47:28,760 takes two strings but what are those 2609 01:47:28,760 --> 01:47:31,719 strings supposed to represent right so 2610 01:47:31,719 --> 01:47:34,239 here we can take a look at what I would 2611 01:47:34,239 --> 01:47:36,920 consider a better interface definition 2612 01:47:36,920 --> 01:47:38,960 where The copier interface actually has 2613 01:47:38,960 --> 01:47:41,360 a copy method that specifies the source 2614 01:47:41,360 --> 01:47:43,920 file is kind of the name of the first 2615 01:47:43,920 --> 01:47:46,560 parameter and the destination file is 2616 01:47:46,560 --> 01:47:48,560 the name of the second parameter and 2617 01:47:48,560 --> 01:47:51,560 then byes copied is the integer that's 2618 01:47:51,560 --> 01:47:54,800 returned so you know the functionality 2619 01:47:54,800 --> 01:47:57,199 here is identical but now we have much 2620 01:47:57,199 --> 01:47:59,920 better I I mean I would consider it 2621 01:47:59,920 --> 01:48:02,080 documentation of what the intention 2622 01:48:02,080 --> 01:48:05,199 behind this interface is so the question 2623 01:48:05,199 --> 01:48:06,840 is are you required to name the 2624 01:48:06,840 --> 01:48:08,280 arguments of an interface in order for 2625 01:48:08,280 --> 01:48:11,679 your code to compile properly uh no no 2626 01:48:11,679 --> 01:48:14,400 it'll work fine either way next question 2627 01:48:14,400 --> 01:48:16,560 is why would you name your interfaces 2628 01:48:16,560 --> 01:48:18,400 methods parameters right like we don't 2629 01:48:18,400 --> 01:48:20,599 need to why would we do it um execution 2630 01:48:20,599 --> 01:48:22,760 speed memory savings or readability and 2631 01:48:22,760 --> 01:48:24,360 Clarity uh it's going to be for 2632 01:48:24,360 --> 01:48:27,599 readability and Clarity type assertions 2633 01:48:27,599 --> 01:48:30,159 so type assertions are something you'll 2634 01:48:30,159 --> 01:48:31,880 see every once in a while I would argue 2635 01:48:31,880 --> 01:48:33,480 they're probably not super common but 2636 01:48:33,480 --> 01:48:35,639 you will come across them um and the 2637 01:48:35,639 --> 01:48:37,119 whole purpose of a type assertion is so 2638 01:48:37,119 --> 01:48:39,239 that you can take an interface and kind 2639 01:48:39,239 --> 01:48:42,880 of cast it back into its underlying type 2640 01:48:42,880 --> 01:48:45,320 so in this code sample here we can kind 2641 01:48:45,320 --> 01:48:48,280 of assume that s is an instance of a 2642 01:48:48,280 --> 01:48:50,360 shape interface and at this point in the 2643 01:48:50,360 --> 01:48:51,920 code because it's just an interface we 2644 01:48:51,920 --> 01:48:54,280 don't know NE neily if it's a circle or 2645 01:48:54,280 --> 01:48:56,440 maybe a square or maybe some other type 2646 01:48:56,440 --> 01:49:00,040 so what we do is we do a type assertion 2647 01:49:00,040 --> 01:49:03,599 to cast it to the circle struct and 2648 01:49:03,599 --> 01:49:05,599 basically what happens here is on the 2649 01:49:05,599 --> 01:49:10,159 left hand side of the um this uh short 2650 01:49:10,159 --> 01:49:12,719 declaration operator here we get back 2651 01:49:12,719 --> 01:49:14,760 the instance of the circle so this is 2652 01:49:14,760 --> 01:49:17,040 going to be an instance of the circle 2653 01:49:17,040 --> 01:49:19,599 struct again the underlying struct um 2654 01:49:19,599 --> 01:49:23,480 behind the shape interface if it was a 2655 01:49:23,480 --> 01:49:25,760 circle right because we we can't be sure 2656 01:49:25,760 --> 01:49:27,080 if we had a shape we're not sure if it 2657 01:49:27,080 --> 01:49:28,920 was a circle or maybe something else but 2658 01:49:28,920 --> 01:49:32,119 this okay variable this is going to be a 2659 01:49:32,119 --> 01:49:36,400 Boolean and if it's true then it was a 2660 01:49:36,400 --> 01:49:38,040 circle and we should have a valid kind 2661 01:49:38,040 --> 01:49:41,800 of filled out Circle struct if okay is 2662 01:49:41,800 --> 01:49:43,599 false then we kind of have to discard 2663 01:49:43,599 --> 01:49:46,119 the circle um because we we weren't able 2664 01:49:46,119 --> 01:49:49,080 to parse out um the shape as a circle 2665 01:49:49,080 --> 01:49:52,119 because it wasn't a circle so let's move 2666 01:49:52,119 --> 01:49:53,840 on to the assign it's an email then it 2667 01:49:53,840 --> 01:49:55,280 should return the email's two address 2668 01:49:55,280 --> 01:49:57,080 and the cost of the email if the expense 2669 01:49:57,080 --> 01:49:58,560 is an SMS then it should return the 2670 01:49:58,560 --> 01:50:01,239 sms's phone number and cost if the 2671 01:50:01,239 --> 01:50:02,800 expense is any other underlying type 2672 01:50:02,800 --> 01:50:05,000 just return an empty string and a 0.0 2673 01:50:05,000 --> 01:50:07,080 for the cost Okay cool so we've got this 2674 01:50:07,080 --> 01:50:09,880 get expense report that takes an expense 2675 01:50:09,880 --> 01:50:13,320 as input and my guess is yep expense is 2676 01:50:13,320 --> 01:50:16,679 this interface so our job is to kind of 2677 01:50:16,679 --> 01:50:19,239 try to cast it into the potential 2678 01:50:19,239 --> 01:50:23,239 underlying types email and SMS 2679 01:50:23,239 --> 01:50:28,639 so first we do um email 2680 01:50:28,639 --> 01:50:32,880 okay uh expense Dot and we'll cast it to 2681 01:50:32,880 --> 01:50:36,520 an email type if 2682 01:50:36,520 --> 01:50:39,119 okay so if it's an email return the 2683 01:50:39,119 --> 01:50:46,880 emails to address so uh return email. to 2684 01:50:47,800 --> 01:50:52,840 address as that string there and also so 2685 01:50:52,840 --> 01:50:56,159 it's cost so email dot looks like cost 2686 01:50:56,159 --> 01:51:00,480 is a method email. cost 2687 01:51:00,480 --> 01:51:06,000 okay uh next we can do s 2688 01:51:06,000 --> 01:51:10,800 okay uh e do cast to an SMS so if it's 2689 01:51:10,800 --> 01:51:13,520 an SMS we can 2690 01:51:13,520 --> 01:51:19,840 return sms's to phone number to phone 2691 01:51:19,840 --> 01:51:23,639 number and the SMS Dot cost I believe 2692 01:51:23,639 --> 01:51:26,639 that's also just yep just a 2693 01:51:26,639 --> 01:51:29,920 method okay and it says otherwise if it 2694 01:51:29,920 --> 01:51:33,719 has a different underlying type return 2695 01:51:33,719 --> 01:51:35,000 empty 2696 01:51:35,000 --> 01:51:40,400 string and 0.0 for the cost okay cool 2697 01:51:40,400 --> 01:51:42,599 that 2698 01:51:42,599 --> 01:51:44,800 feels at least like we followed the 2699 01:51:44,800 --> 01:51:47,040 instructions let's see what we 2700 01:51:47,040 --> 01:51:50,440 get not enough arguments in call to sms. 2701 01:51:50,440 --> 01:51:53,920 cost let's take a look at sms. cost 2702 01:51:53,920 --> 01:51:56,239 cost 2703 01:51:56,239 --> 01:51:58,239 H have 2704 01:51:58,239 --> 01:52:02,760 want what did I screw up 2705 01:52:03,440 --> 01:52:07,560 here ah should be s. cost I I named I 2706 01:52:07,560 --> 01:52:09,800 named this truck the struct S all right 2707 01:52:09,800 --> 01:52:12,360 let's try that 2708 01:52:12,560 --> 01:52:15,040 again report the email going to John do 2709 01:52:15,040 --> 01:52:20,159 will cost 11 email the sms okay cool and 2710 01:52:20,159 --> 01:52:22,800 invalid expense perfect that I mean that 2711 01:52:22,800 --> 01:52:24,159 feels right I can come down here and 2712 01:52:24,159 --> 01:52:27,440 check the test Suite yeah invalid okay 2713 01:52:27,440 --> 01:52:29,920 cool let's submit that when we want to 2714 01:52:29,920 --> 01:52:32,239 do a lot of successive type assertions 2715 01:52:32,239 --> 01:52:34,199 in a row there's actually a better way 2716 01:52:34,199 --> 01:52:36,679 and that's with type switches so here's 2717 01:52:36,679 --> 01:52:39,440 a Syntax for a type switch uh basically 2718 01:52:39,440 --> 01:52:43,040 we have an interface and we cast it um 2719 01:52:43,040 --> 01:52:44,560 at the very top of the switch and then 2720 01:52:44,560 --> 01:52:46,000 we can actually check and kind of 2721 01:52:46,000 --> 01:52:49,360 pattern match against different possible 2722 01:52:49,360 --> 01:52:52,000 types if none of the types that we've 2723 01:52:52,000 --> 01:52:54,280 specified are the matching underlying 2724 01:52:54,280 --> 01:52:56,679 type then it will kind of fall down to 2725 01:52:56,679 --> 01:52:59,159 the default case so let's write some 2726 01:52:59,159 --> 01:53:01,239 code and see how it works um down in the 2727 01:53:01,239 --> 01:53:02,840 assignment it says after submitting our 2728 01:53:02,840 --> 01:53:04,560 last snippet of code for review a more 2729 01:53:04,560 --> 01:53:07,560 experienced gopher or term for a go 2730 01:53:07,560 --> 01:53:09,320 developer uh told us to use a type 2731 01:53:09,320 --> 01:53:11,920 switch instead of successive assertions 2732 01:53:11,920 --> 01:53:13,920 let's make that Improvement implement 2733 01:53:13,920 --> 01:53:16,119 the get expense report function using a 2734 01:53:16,119 --> 01:53:19,520 type switch Okay cool so kind of the 2735 01:53:19,520 --> 01:53:21,920 same thing though if it's an email 2736 01:53:21,920 --> 01:53:23,520 return a to address and a cost if it's 2737 01:53:23,520 --> 01:53:25,040 an SMS then we should return a phone 2738 01:53:25,040 --> 01:53:27,440 number and a cost blah blah blah right 2739 01:53:27,440 --> 01:53:28,560 the difference is we're going to use a 2740 01:53:28,560 --> 01:53:31,079 different syntax this time okay so we're 2741 01:53:31,079 --> 01:53:36,239 going to be using this switch syntax so 2742 01:53:36,599 --> 01:53:42,520 switch value colon equals e.type 2743 01:53:42,520 --> 01:53:46,840 okay Open brackets case um we are 2744 01:53:46,840 --> 01:53:50,079 interested in if the expense is an 2745 01:53:50,079 --> 01:53:52,480 email so case email now the the 2746 01:53:52,480 --> 01:53:53,960 interesting thing is with now within 2747 01:53:53,960 --> 01:53:57,719 this case block V is an email so I can 2748 01:53:57,719 --> 01:53:59,239 treat it like an email so I can do 2749 01:53:59,239 --> 01:54:01,639 return V 2750 01:54:01,639 --> 01:54:04,880 Dot oh what was it two address I think 2751 01:54:04,880 --> 01:54:07,679 yeah two 2752 01:54:07,679 --> 01:54:11,239 address b. 2753 01:54:11,239 --> 01:54:14,719 cost a 2754 01:54:14,719 --> 01:54:19,639 SMS return B do two phone number I think 2755 01:54:19,639 --> 01:54:24,480 it was two phone number b. 2756 01:54:24,480 --> 01:54:27,199 cost and 2757 01:54:27,199 --> 01:54:29,159 default 2758 01:54:29,159 --> 01:54:31,719 return uh I think it was empty string 2759 01:54:31,719 --> 01:54:34,960 just zero values right empty string and 2760 01:54:34,960 --> 01:54:38,199 0.0 okay cool let's see what 2761 01:54:38,199 --> 01:54:40,920 happens with that oh am I forgetting 2762 01:54:40,920 --> 01:54:41,920 nope I've 2763 01:54:41,920 --> 01:54:44,520 got oh I'm indenting a little 2764 01:54:44,520 --> 01:54:48,639 weird there we go let's run 2765 01:54:48,639 --> 01:54:52,119 that cool the MS SMS is going to be is 2766 01:54:52,119 --> 01:54:54,199 going to this number with this 2767 01:54:54,199 --> 01:54:57,079 cost got some emails and costs okay 2768 01:54:57,079 --> 01:54:58,920 that's looking good to me now that we've 2769 01:54:58,920 --> 01:55:01,280 learned what interfaces are and how we 2770 01:55:01,280 --> 01:55:03,199 use them let's talk about how we can use 2771 01:55:03,199 --> 01:55:05,480 them more effective and in a sort of 2772 01:55:05,480 --> 01:55:08,960 idiomatic and clean way if you forget 2773 01:55:08,960 --> 01:55:10,880 all of the other advice that we're going 2774 01:55:10,880 --> 01:55:12,719 to go over when it comes to writing 2775 01:55:12,719 --> 01:55:15,119 clean interfaces don't forget this one 2776 01:55:15,119 --> 01:55:17,719 and that is to keep interfaces as small 2777 01:55:17,719 --> 01:55:20,719 as you can the best the cleanest and the 2778 01:55:20,719 --> 01:55:22,840 most useful interfaces typically just 2779 01:55:22,840 --> 01:55:25,920 have one or two methods defined on them 2780 01:55:25,920 --> 01:55:29,000 imagine a simple Stringer interface it 2781 01:55:29,000 --> 01:55:30,760 has one method defined on it called 2782 01:55:30,760 --> 01:55:33,280 string that simply returns a string you 2783 01:55:33,280 --> 01:55:36,159 can take that interface and implement it 2784 01:55:36,159 --> 01:55:38,480 on basically any type and now you have a 2785 01:55:38,480 --> 01:55:41,199 super useful interface for logging out 2786 01:55:41,199 --> 01:55:43,079 string representations of different 2787 01:55:43,079 --> 01:55:45,719 types there isn't a hard and fast rule 2788 01:55:45,719 --> 01:55:47,560 about exactly how many methods you 2789 01:55:47,560 --> 01:55:49,639 should be defining on your interfaces 2790 01:55:49,639 --> 01:55:51,440 but what you really should be doing is 2791 01:55:51,440 --> 01:55:54,560 looking for kind of the minimal Behavior 2792 01:55:54,560 --> 01:55:56,679 necessary to accurately represent an 2793 01:55:56,679 --> 01:55:59,360 idea or concept right so for example 2794 01:55:59,360 --> 01:56:02,360 here's a slightly larger interface from 2795 01:56:02,360 --> 01:56:04,159 the standard Library again normally 2796 01:56:04,159 --> 01:56:05,520 we'll see interfaces in the standard 2797 01:56:05,520 --> 01:56:07,760 library with maybe just one or two or 2798 01:56:07,760 --> 01:56:11,239 three uh methods this one has five but 2799 01:56:11,239 --> 01:56:14,480 this is kind of still the minimum um 2800 01:56:14,480 --> 01:56:16,920 amount or or the the the minimal 2801 01:56:16,920 --> 01:56:18,960 necessary behavior that we need to 2802 01:56:18,960 --> 01:56:21,599 describe a file like a file in your file 2803 01:56:21,599 --> 01:56:23,520 system right we need a way to close the 2804 01:56:23,520 --> 01:56:25,520 file we need a way to read it we need a 2805 01:56:25,520 --> 01:56:28,480 way to seek to individual uh kind of 2806 01:56:28,480 --> 01:56:32,320 sections of the file um so this is an 2807 01:56:32,320 --> 01:56:34,360 example of a slightly larger interface 2808 01:56:34,360 --> 01:56:35,880 right I would say five methods is 2809 01:56:35,880 --> 01:56:38,840 definitely a on the larger end um but 2810 01:56:38,840 --> 01:56:41,840 it's still a good interface because it's 2811 01:56:41,840 --> 01:56:44,360 using as as little Behavior as it 2812 01:56:44,360 --> 01:56:47,040 possibly can to describe an operating 2813 01:56:47,040 --> 01:56:49,280 system file so the question that goes 2814 01:56:49,280 --> 01:56:51,520 along with this is interfaces should 2815 01:56:51,520 --> 01:56:54,400 have as blank methods as possible and 2816 01:56:54,400 --> 01:56:56,639 the answers are complex few and many and 2817 01:56:56,639 --> 01:56:59,800 the answer is going to be few the next 2818 01:56:59,800 --> 01:57:02,079 mistake that I've seen new go developers 2819 01:57:02,079 --> 01:57:04,719 make is when they write an interface 2820 01:57:04,719 --> 01:57:08,119 that sort of knows about the types that 2821 01:57:08,119 --> 01:57:11,199 they've intended to satisfy it so for 2822 01:57:11,199 --> 01:57:14,079 example if you have a car interface and 2823 01:57:14,079 --> 01:57:17,280 you've defined an is fire truck method 2824 01:57:17,280 --> 01:57:19,760 on the car interface that returns a buou 2825 01:57:19,760 --> 01:57:21,119 you know whether or not it's a fire 2826 01:57:21,119 --> 01:57:23,119 truck that's probably a mistake you 2827 01:57:23,119 --> 01:57:25,119 would actually just want to use a type 2828 01:57:25,119 --> 01:57:27,040 assertion or a type switch if you really 2829 01:57:27,040 --> 01:57:29,840 needed to figure out the underlying type 2830 01:57:29,840 --> 01:57:31,920 you should not make your interfaces 2831 01:57:31,920 --> 01:57:34,079 aware of the underlying types this also 2832 01:57:34,079 --> 01:57:35,800 breaks rule number one right because 2833 01:57:35,800 --> 01:57:37,960 rule number one we don't need to know if 2834 01:57:37,960 --> 01:57:40,639 a car is a firetr for like the minimal 2835 01:57:40,639 --> 01:57:43,800 behavior of a car I mean you can see how 2836 01:57:43,800 --> 01:57:45,760 this sort of design pattern would get 2837 01:57:45,760 --> 01:57:47,679 out of hand very quickly because we 2838 01:57:47,679 --> 01:57:49,840 might need to also Define other booleans 2839 01:57:49,840 --> 01:57:53,280 like is pickup is sedan is tank right if 2840 01:57:53,280 --> 01:57:55,079 you start catering to all of the 2841 01:57:55,079 --> 01:57:57,280 underlying types of a given interface 2842 01:57:57,280 --> 01:57:58,599 your interface is going to be really 2843 01:57:58,599 --> 01:58:01,040 bloated and become very very large so 2844 01:58:01,040 --> 01:58:02,760 the question here is actually the 2845 01:58:02,760 --> 01:58:05,560 reverse it says it's okay for types to 2846 01:58:05,560 --> 01:58:07,639 be aware of the interfaces that they 2847 01:58:07,639 --> 01:58:09,960 satisfy if it were flipped around the 2848 01:58:09,960 --> 01:58:11,800 answer would definitely be false but 2849 01:58:11,800 --> 01:58:12,960 because we're talking about the types 2850 01:58:12,960 --> 01:58:14,520 being aware of the interfaces they 2851 01:58:14,520 --> 01:58:16,400 satisfy I don't think that's necessarily 2852 01:58:16,400 --> 01:58:18,760 a problem um they don't need to be aware 2853 01:58:18,760 --> 01:58:22,119 of them right because again in go uh 2854 01:58:22,119 --> 01:58:24,119 interfaces are satisfied implicitly but 2855 01:58:24,119 --> 01:58:26,119 I would argue to some extent they are 2856 01:58:26,119 --> 01:58:28,040 aware of them because the developer had 2857 01:58:28,040 --> 01:58:31,599 to go in some cases out of their way to 2858 01:58:31,599 --> 01:58:33,280 satisfy the implementation of an 2859 01:58:33,280 --> 01:58:35,079 interface so I'm going to go with true 2860 01:58:35,079 --> 01:58:37,639 on this one so now this is the reverse 2861 01:58:37,639 --> 01:58:38,880 question it says it's okay for 2862 01:58:38,880 --> 01:58:40,599 interfaces to be aware of the types that 2863 01:58:40,599 --> 01:58:43,599 satisfy them no they should not be aware 2864 01:58:43,599 --> 01:58:45,280 finally I just want to talk about how 2865 01:58:45,280 --> 01:58:47,840 interfaces are not classes sometimes 2866 01:58:47,840 --> 01:58:49,239 this can get mixed up especially if 2867 01:58:49,239 --> 01:58:50,760 you're coming from an object-oriented 2868 01:58:50,760 --> 01:58:53,119 background um inter Es are just a very 2869 01:58:53,119 --> 01:58:55,199 different idea interfaces are not 2870 01:58:55,199 --> 01:58:57,000 classes they are much Slimmer right 2871 01:58:57,000 --> 01:58:58,599 classes have a lot of functionality 2872 01:58:58,599 --> 01:59:00,960 going on inheritance is a fairly complex 2873 01:59:00,960 --> 01:59:04,679 topic um interfaces are honestly just a 2874 01:59:04,679 --> 01:59:07,760 simpler idea um interfaces don't have 2875 01:59:07,760 --> 01:59:09,560 Constructors or deconstructors that 2876 01:59:09,560 --> 01:59:11,199 require that data is created or 2877 01:59:11,199 --> 01:59:12,679 destroyed right so that's another way 2878 01:59:12,679 --> 01:59:14,760 that they differ from classes that have 2879 01:59:14,760 --> 01:59:17,800 kind of this in inherent setup and tear 2880 01:59:17,800 --> 01:59:20,920 down uh situation interfaces are not 2881 01:59:20,920 --> 01:59:23,760 hierarchical right there's there's no uh 2882 01:59:23,760 --> 01:59:25,800 hierarchical inheritance tree when it 2883 01:59:25,800 --> 01:59:28,040 comes to interfaces and the most 2884 01:59:28,040 --> 01:59:30,320 interesting one is that interfaces 2885 01:59:30,320 --> 01:59:33,000 Define functions signatures but not 2886 01:59:33,000 --> 01:59:35,360 underlying Behavior right so this is 2887 01:59:35,360 --> 01:59:37,639 actually a big difference between 2888 01:59:37,639 --> 01:59:41,400 interfaces in classes in a class A Child 2889 01:59:41,400 --> 01:59:44,199 class can inherit behavior from a parent 2890 01:59:44,199 --> 01:59:46,360 class which can kind of dry up your code 2891 01:59:46,360 --> 01:59:49,000 right don't repeat yourself in go that's 2892 01:59:49,000 --> 01:59:50,520 not the case at all an interface doesn't 2893 01:59:50,520 --> 01:59:52,400 dry up your code you still have to go 2894 01:59:52,400 --> 01:59:54,280 Implement all of the methods on all of 2895 01:59:54,280 --> 01:59:56,480 the different types individually 2896 01:59:56,480 --> 01:59:58,639 interfaces just allow us to use all of 2897 01:59:58,639 --> 02:00:01,760 those types kind of in the same places 2898 02:00:01,760 --> 02:00:03,920 later in this course we'll get to talk 2899 02:00:03,920 --> 02:00:07,400 about generics which is a way to kind of 2900 02:00:07,400 --> 02:00:10,119 dry up your code and funny enough kind 2901 02:00:10,119 --> 02:00:13,320 of uses interfaces um under the hood or 2902 02:00:13,320 --> 02:00:16,679 kind of as a part of the generic system 2903 02:00:16,679 --> 02:00:19,400 to make that happen so finally the 2904 02:00:19,400 --> 02:00:21,239 question is interfaces allow you to 2905 02:00:21,239 --> 02:00:23,599 define a method's Behavior once and use 2906 02:00:23,599 --> 02:00:26,800 it for many different types uh that's 2907 02:00:26,800 --> 02:00:29,960 false go has a very unique way of 2908 02:00:29,960 --> 02:00:32,400 handling errors really quickly let's 2909 02:00:32,400 --> 02:00:35,000 review how JavaScript handles errors and 2910 02:00:35,000 --> 02:00:36,320 the way JavaScript handles errors is 2911 02:00:36,320 --> 02:00:38,920 very similar to python or Java it uses a 2912 02:00:38,920 --> 02:00:41,199 TR catch Paradigm um and let's contrast 2913 02:00:41,199 --> 02:00:43,679 that with how go handles errors in its 2914 02:00:43,679 --> 02:00:45,760 sort of unique way let's pretend that we 2915 02:00:45,760 --> 02:00:48,520 have a function called get user um and 2916 02:00:48,520 --> 02:00:50,360 we'll start with JavaScript so we have a 2917 02:00:50,360 --> 02:00:52,679 function called get user 2918 02:00:52,679 --> 02:00:56,239 whoa and it Returns the user so we'll do 2919 02:00:56,239 --> 02:00:59,560 const user equals get user and we have 2920 02:00:59,560 --> 02:01:01,960 to wrap the get user function the call 2921 02:01:01,960 --> 02:01:04,199 to the get user function and a tri block 2922 02:01:04,199 --> 02:01:05,840 because we know that the get user 2923 02:01:05,840 --> 02:01:07,239 function can throw because let's just 2924 02:01:07,239 --> 02:01:09,679 say for example uh maybe the user 2925 02:01:09,679 --> 02:01:12,520 doesn't exist Okay cool so if something 2926 02:01:12,520 --> 02:01:16,280 goes wrong we add a catch block and if 2927 02:01:16,280 --> 02:01:18,679 this function throws execution will stop 2928 02:01:18,679 --> 02:01:20,119 we'll enter the catch block and do 2929 02:01:20,119 --> 02:01:22,199 whatever is in here for now we can just 2930 02:01:22,199 --> 02:01:23,800 uh console. 2931 02:01:23,800 --> 02:01:26,560 log the error now let's take a look at 2932 02:01:26,560 --> 02:01:29,239 what this function looks like in go we 2933 02:01:29,239 --> 02:01:32,719 do something like this we do user air 2934 02:01:32,719 --> 02:01:36,239 colon equals get 2935 02:01:38,199 --> 02:01:42,320 user if Air does not equal 2936 02:01:42,320 --> 02:01:45,599 nil then we could print out the error 2937 02:01:45,599 --> 02:01:48,719 and return so that we don't continue and 2938 02:01:48,719 --> 02:01:51,199 then down here we could you know deal 2939 02:01:51,199 --> 02:01:55,719 with the user object so uh use user here 2940 02:01:55,719 --> 02:01:57,800 and for consistency sake we could say 2941 02:01:57,800 --> 02:02:00,679 use user here um after the user object 2942 02:02:00,679 --> 02:02:03,119 is created in JavaScript okay so what's 2943 02:02:03,119 --> 02:02:04,760 the difference well let's talk about the 2944 02:02:04,760 --> 02:02:07,159 first reason why I prefer goes error 2945 02:02:07,159 --> 02:02:09,960 handling to javascript's error handling 2946 02:02:09,960 --> 02:02:11,920 let's pretend we need to go get some 2947 02:02:11,920 --> 02:02:15,119 data for the user after we've already 2948 02:02:15,119 --> 02:02:17,199 kind of retrieved the user successfully 2949 02:02:17,199 --> 02:02:18,400 so let's say we need to go get the 2950 02:02:18,400 --> 02:02:21,400 user's profile picture well in go all we 2951 02:02:21,400 --> 02:02:22,960 would do 2952 02:02:22,960 --> 02:02:24,920 is call the next dangerous function 2953 02:02:24,920 --> 02:02:28,880 let's say get user Pro profile and maybe 2954 02:02:28,880 --> 02:02:32,760 it takes a user. ID as input right so we 2955 02:02:32,760 --> 02:02:34,679 need to successfully wait for the user 2956 02:02:34,679 --> 02:02:37,159 to come back and then we can go fetch 2957 02:02:37,159 --> 02:02:39,040 its 2958 02:02:39,040 --> 02:02:41,599 profile right so this looks very similar 2959 02:02:41,599 --> 02:02:44,159 we doing another dangerous function get 2960 02:02:44,159 --> 02:02:46,880 user profile and it returns a profile 2961 02:02:46,880 --> 02:02:49,199 and an error if an error with the 2962 02:02:49,199 --> 02:02:51,400 profile occurs uh again we'll just kind 2963 02:02:51,400 --> 02:02:52,800 of print out the error and return 2964 02:02:52,800 --> 02:02:55,719 otherwise now we have a profile object 2965 02:02:55,719 --> 02:02:58,560 okay what would we do in JavaScript well 2966 02:02:58,560 --> 02:03:00,760 in JavaScript we can't just take this 2967 02:03:00,760 --> 02:03:04,239 Tri catch and paste it down here and 2968 02:03:04,239 --> 02:03:06,440 update some stuff this will not work if 2969 02:03:06,440 --> 02:03:08,960 we do get user profile 2970 02:03:08,960 --> 02:03:10,639 user. 2971 02:03:10,639 --> 02:03:13,639 ID 2972 02:03:13,639 --> 02:03:16,880 profile the problem with this code is 2973 02:03:16,880 --> 02:03:20,320 that user is only available within this 2974 02:03:20,320 --> 02:03:23,880 Tri Block it's scoped to the tri block 2975 02:03:23,880 --> 02:03:26,599 right so this user object here will be 2976 02:03:26,599 --> 02:03:28,880 undefined so the normal thing to do in 2977 02:03:28,880 --> 02:03:31,560 JavaScript would just be to take this 2978 02:03:31,560 --> 02:03:34,719 line here and inject it 2979 02:03:34,719 --> 02:03:38,199 within the tri block the original Tri 2980 02:03:38,199 --> 02:03:40,320 block right so now I'm doing my second 2981 02:03:40,320 --> 02:03:42,639 dangerous function after I do my first 2982 02:03:42,639 --> 02:03:44,960 dangerous function the reason I don't 2983 02:03:44,960 --> 02:03:48,119 like this is that the logic for handling 2984 02:03:48,119 --> 02:03:51,520 the errors is now all in one place if I 2985 02:03:51,520 --> 02:03:54,159 want want to handle the error for the 2986 02:03:54,159 --> 02:03:56,880 get user profile function differently or 2987 02:03:56,880 --> 02:03:59,239 separately um then I want to handle the 2988 02:03:59,239 --> 02:04:00,920 error from the get user function I have 2989 02:04:00,920 --> 02:04:03,760 to actually Nest the whole Tri 2990 02:04:03,760 --> 02:04:06,239 catch like 2991 02:04:06,239 --> 02:04:09,840 this right so now user. ID is accessible 2992 02:04:09,840 --> 02:04:12,119 because I'm in the same Tri block but I 2993 02:04:12,119 --> 02:04:14,480 get a second catch block so we kind of 2994 02:04:14,480 --> 02:04:17,199 get this nasty nesting if we want to 2995 02:04:17,199 --> 02:04:19,880 treat each individual error separately 2996 02:04:19,880 --> 02:04:21,960 and this kind of brings us to the second 2997 02:04:21,960 --> 02:04:24,480 reason why I prefer Go's error handling 2998 02:04:24,480 --> 02:04:26,880 and it's that it forces us to think 2999 02:04:26,880 --> 02:04:29,599 about each individual error that's 3000 02:04:29,599 --> 02:04:32,360 passed back from a dangerous function so 3001 02:04:32,360 --> 02:04:34,079 again in JavaScript kind of the normal 3002 02:04:34,079 --> 02:04:36,360 thing to do unless you really needed 3003 02:04:36,360 --> 02:04:38,159 separate error handling would be to just 3004 02:04:38,159 --> 02:04:39,840 kind of do all of your dangerous stuff 3005 02:04:39,840 --> 02:04:42,480 in one large Tri block the problem with 3006 02:04:42,480 --> 02:04:46,440 this in my opinion is that it kind of it 3007 02:04:46,440 --> 02:04:48,880 doesn't encourage me to remember which 3008 02:04:48,880 --> 02:04:50,960 of these functions is dangerous in the 3009 02:04:50,960 --> 02:04:52,920 first place for example maybe this is a 3010 02:04:52,920 --> 02:04:54,679 safe function and this is a dangerous 3011 02:04:54,679 --> 02:04:56,000 function that can potentially throw an 3012 02:04:56,000 --> 02:04:58,599 error but looking at this code from um 3013 02:04:58,599 --> 02:05:00,719 kind of a calling perspective I don't 3014 02:05:00,719 --> 02:05:02,599 really know that that's the case whereas 3015 02:05:02,599 --> 02:05:06,480 in go because a function returns kind of 3016 02:05:06,480 --> 02:05:09,599 the valid data and the error with every 3017 02:05:09,599 --> 02:05:12,360 function call I know for a fact that the 3018 02:05:12,360 --> 02:05:16,639 get user profile function can throw an 3019 02:05:16,639 --> 02:05:19,840 error because it returns an error value 3020 02:05:19,840 --> 02:05:21,400 this will probably make more sense if I 3021 02:05:21,400 --> 02:05:22,320 actually write out some of these 3022 02:05:22,320 --> 02:05:24,360 functions so in JavaScript the get user 3023 02:05:24,360 --> 02:05:26,000 function might look just like this 3024 02:05:26,000 --> 02:05:28,520 function get 3025 02:05:28,520 --> 02:05:33,000 user uh we could say uh do some get user 3026 02:05:33,000 --> 02:05:35,119 logic 3027 02:05:35,119 --> 02:05:38,559 here and then maybe it returns you know 3028 02:05:38,559 --> 02:05:39,719 a 3029 02:05:39,719 --> 02:05:42,320 user looking at the function 3030 02:05:42,320 --> 02:05:45,440 signature all I can tell in JavaScript 3031 02:05:45,440 --> 02:05:48,000 is that this function takes no arguments 3032 02:05:48,000 --> 02:05:49,239 and the only way for me to know what it 3033 02:05:49,239 --> 02:05:50,679 returns is to go find that return 3034 02:05:50,679 --> 02:05:53,599 statement see oh okay it returns a user 3035 02:05:53,599 --> 02:05:56,719 however in go I actually get two super 3036 02:05:56,719 --> 02:05:59,000 helpful things in the function signature 3037 02:05:59,000 --> 02:06:00,360 and remember the function signature is 3038 02:06:00,360 --> 02:06:02,639 just kind of that first line of a 3039 02:06:02,639 --> 02:06:04,440 function definition so in go if I were 3040 02:06:04,440 --> 02:06:06,440 to write the function definition for the 3041 02:06:06,440 --> 02:06:07,440 get user function would be something 3042 02:06:07,440 --> 02:06:08,280 like this 3043 02:06:08,280 --> 02:06:12,599 funk get user doesn't take any inputs 3044 02:06:12,599 --> 02:06:17,040 but it returns a let's say a user struct 3045 02:06:17,040 --> 02:06:20,559 and an error right and then we have some 3046 02:06:20,559 --> 02:06:23,599 kind of do get user logic 3047 02:06:23,599 --> 02:06:26,679 here right so now just by looking at 3048 02:06:26,679 --> 02:06:29,159 this function signature I can tell that 3049 02:06:29,159 --> 02:06:31,440 it returns a user and that it could 3050 02:06:31,440 --> 02:06:33,679 possibly return an error as well that I 3051 02:06:33,679 --> 02:06:35,679 need to go handle whereas again in 3052 02:06:35,679 --> 02:06:38,320 JavaScript not only do I not get to see 3053 02:06:38,320 --> 02:06:40,000 in the function signature what is 3054 02:06:40,000 --> 02:06:42,040 potentially returned but I also don't 3055 02:06:42,040 --> 02:06:44,280 know that this function can throw I have 3056 02:06:44,280 --> 02:06:46,840 to kind of go digging deeper into the 3057 02:06:46,840 --> 02:06:49,719 function definition to see if there's 3058 02:06:49,719 --> 02:06:52,239 potentially something uh dangerous going 3059 02:06:52,239 --> 02:06:54,480 on in the meat of the function so again 3060 02:06:54,480 --> 02:06:56,280 to reiterate because this is actually a 3061 02:06:56,280 --> 02:06:57,920 super important point when you're 3062 02:06:57,920 --> 02:06:59,920 learning about how errors are handled in 3063 02:06:59,920 --> 02:07:03,320 go the primary reason I like error 3064 02:07:03,320 --> 02:07:06,199 handling in go is that it forces me as I 3065 02:07:06,199 --> 02:07:09,599 write my code to be kind of hyper aware 3066 02:07:09,599 --> 02:07:12,920 of every potential error and make sure 3067 02:07:12,920 --> 02:07:15,719 that I write code that handles it so now 3068 02:07:15,719 --> 02:07:17,840 that we understand what error handling 3069 02:07:17,840 --> 02:07:19,400 in go kind of looks like from a high 3070 02:07:19,400 --> 02:07:22,239 level let's dive into the detail s 3071 02:07:22,239 --> 02:07:25,280 errors in go are just values and 3072 02:07:25,280 --> 02:07:27,599 specifically they're just interfaces so 3073 02:07:27,599 --> 02:07:30,000 the built-in error interface is an 3074 02:07:30,000 --> 02:07:32,599 interface with a single method the error 3075 02:07:32,599 --> 02:07:34,920 method and that method returns a string 3076 02:07:34,920 --> 02:07:37,639 describing what went wrong so how do we 3077 02:07:37,639 --> 02:07:39,239 actually go about handling errors in 3078 02:07:39,239 --> 02:07:41,280 code well let's take a look at this 3079 02:07:41,280 --> 02:07:42,960 function right here so this is a 3080 02:07:42,960 --> 02:07:44,599 function in the standard Library it's 3081 02:07:44,599 --> 02:07:47,000 called asky to integer it takes a string 3082 02:07:47,000 --> 02:07:48,599 and attempts to convert it into an 3083 02:07:48,599 --> 02:07:50,760 integer value and potentially that can 3084 02:07:50,760 --> 02:07:52,719 be problematic right because you can 3085 02:07:52,719 --> 02:07:55,360 write strings that aren't numbers under 3086 02:07:55,360 --> 02:07:57,559 the hood Okay cool so what do we do we 3087 02:07:57,559 --> 02:08:00,719 get back an integer and an error and in 3088 02:08:00,719 --> 02:08:03,320 essence it's it's it's really simple the 3089 02:08:03,320 --> 02:08:07,760 error is either nil or it's not nil if 3090 02:08:07,760 --> 02:08:10,079 it is nil that means everything went 3091 02:08:10,079 --> 02:08:12,480 fine and nothing went wrong so if the 3092 02:08:12,480 --> 02:08:15,679 error is nil it means there is no kind 3093 02:08:15,679 --> 02:08:18,079 of string representing what went wrong 3094 02:08:18,079 --> 02:08:20,480 because nothing went wrong however if 3095 02:08:20,480 --> 02:08:23,159 the error is not nil that means 3096 02:08:23,159 --> 02:08:25,880 something did go wrong right so if the 3097 02:08:25,880 --> 02:08:28,639 error is not nil in this case then we'll 3098 02:08:28,639 --> 02:08:31,079 print an error message and return from 3099 02:08:31,079 --> 02:08:33,480 the function right so we're basically 3100 02:08:33,480 --> 02:08:36,599 writing guard Clauses that say something 3101 02:08:36,599 --> 02:08:38,800 went wrong let's handle this error and 3102 02:08:38,800 --> 02:08:41,159 get out of here right enough talk let's 3103 02:08:41,159 --> 02:08:42,920 write some code so you can see what I 3104 02:08:42,920 --> 02:08:45,239 mean let me expand this so it's a little 3105 02:08:45,239 --> 02:08:47,440 easier to see the code okay the 3106 02:08:47,440 --> 02:08:49,239 assignment says we offer a product that 3107 02:08:49,239 --> 02:08:51,559 allows businesses that use texo to to 3108 02:08:51,559 --> 02:08:53,679 send pairs of messages to couples it's 3109 02:08:53,679 --> 02:08:55,119 mostly used by flower shops and movie 3110 02:08:55,119 --> 02:08:57,480 theaters okay great complete the send 3111 02:08:57,480 --> 02:08:59,119 SMS to couple function so that's this 3112 02:08:59,119 --> 02:09:00,719 function here it should send two 3113 02:09:00,719 --> 02:09:02,440 messages first to the customer and then 3114 02:09:02,440 --> 02:09:06,559 to the customer's spouse so use send SMS 3115 02:09:06,559 --> 02:09:08,800 to send the message to customer if an 3116 02:09:08,800 --> 02:09:11,320 error is encountered return 0.0 and the 3117 02:09:11,320 --> 02:09:13,520 error uh do the same for message to 3118 02:09:13,520 --> 02:09:15,159 spouse if both messages are sent 3119 02:09:15,159 --> 02:09:16,800 successfully return the total cost of 3120 02:09:16,800 --> 02:09:19,920 the messages added together okay I think 3121 02:09:19,920 --> 02:09:21,559 I understand what's going on so we're 3122 02:09:21,559 --> 02:09:22,880 basically going to send both of these 3123 02:09:22,880 --> 02:09:25,320 messages one after the other um if any 3124 02:09:25,320 --> 02:09:28,159 errors happen we kind of abort early and 3125 02:09:28,159 --> 02:09:29,800 return the 3126 02:09:29,800 --> 02:09:34,679 error okay so uh send SMS takes a 3127 02:09:34,679 --> 02:09:39,280 message as input so first we'll say uh 3128 02:09:39,280 --> 02:09:42,679 send SMS and we'll send the message to 3129 02:09:42,679 --> 02:09:44,639 the 3130 02:09:44,639 --> 02:09:48,239 customer and send SMS returns a float 64 3131 02:09:48,239 --> 02:09:50,920 and error so we'll say um I think it's 3132 02:09:50,920 --> 02:09:53,320 the cost 3133 02:09:53,599 --> 02:09:55,840 return the total cost okay yeah so cost 3134 02:09:55,840 --> 02:09:59,239 error send SMS all right if error does 3135 02:09:59,239 --> 02:10:01,159 not equal nil so if there was a problem 3136 02:10:01,159 --> 02:10:02,719 sending the 3137 02:10:02,719 --> 02:10:05,760 SMS uh return 0.0 and the error so 3138 02:10:05,760 --> 02:10:07,960 return 3139 02:10:12,639 --> 02:10:15,559 0.0 right because this function send SMS 3140 02:10:15,559 --> 02:10:18,360 to couple Returns the total cost and an 3141 02:10:18,360 --> 02:10:20,079 error so we're saying if we failed to 3142 02:10:20,079 --> 02:10:23,440 send the SMS then it costs nothing and 3143 02:10:23,440 --> 02:10:25,599 we'll return the error that describes 3144 02:10:25,599 --> 02:10:26,559 what went 3145 02:10:26,559 --> 02:10:28,599 wrong otherwise we'll do it for the 3146 02:10:28,599 --> 02:10:30,440 message to spouse so we kind of are just 3147 02:10:30,440 --> 02:10:32,480 going to do this exact same thing so I'm 3148 02:10:32,480 --> 02:10:38,119 going to say cost for uh for let's say 3149 02:10:38,400 --> 02:10:41,119 customer cost for 3150 02:10:41,119 --> 02:10:43,119 spouse and we'll be sending the message 3151 02:10:43,119 --> 02:10:44,880 to the 3152 02:10:44,880 --> 02:10:46,559 spouse 3153 02:10:46,559 --> 02:10:48,719 cool all right now if we get to the 3154 02:10:48,719 --> 02:10:49,960 bottom of the function that means 3155 02:10:49,960 --> 02:10:52,960 nothing went wrong so we can 3156 02:10:52,960 --> 02:10:54,960 return cost for 3157 02:10:54,960 --> 02:10:59,000 customer Plus cost for 3158 02:10:59,000 --> 02:11:03,079 spouse and nil right because if we get 3159 02:11:03,079 --> 02:11:04,559 down here nothing went wrong so we don't 3160 02:11:04,559 --> 02:11:06,679 have an error to return okay let's go 3161 02:11:06,679 --> 02:11:10,040 ahead and run this code and see what we 3162 02:11:10,040 --> 02:11:12,320 get and I want to just scroll down and 3163 02:11:12,320 --> 02:11:13,960 take a look at some of these test 3164 02:11:13,960 --> 02:11:16,280 cases okay message for customer thanks 3165 02:11:16,280 --> 02:11:17,679 for coming into our flower shop message 3166 02:11:17,679 --> 02:11:19,320 for spouse we hope you enjoyed your gift 3167 02:11:19,320 --> 02:11:22,000 error can't send texts over 25 3168 02:11:22,000 --> 02:11:24,199 characters Okay cool so I mean if we 3169 02:11:24,199 --> 02:11:26,760 look at the send SMS uh function it 3170 02:11:26,760 --> 02:11:28,880 actually throws an error or I shouldn't 3171 02:11:28,880 --> 02:11:31,040 say throws because we don't throw in go 3172 02:11:31,040 --> 02:11:33,559 right but returns an error value that 3173 02:11:33,559 --> 02:11:35,960 says can't send texts over blank 3174 02:11:35,960 --> 02:11:39,320 characters so that looks correct to me 3175 02:11:39,320 --> 02:11:41,040 um here we've got message to customer 3176 02:11:41,040 --> 02:11:43,320 message to spouse total 3177 02:11:43,320 --> 02:11:45,679 cost okay this is looking pretty good to 3178 02:11:45,679 --> 02:11:47,280 me I'm going to go ahead and submit that 3179 02:11:47,280 --> 02:11:49,320 we talked about how error handling in go 3180 02:11:49,320 --> 02:11:51,480 is all built around the error interface 3181 02:11:51,480 --> 02:11:53,040 in fact let's just review that really 3182 02:11:53,040 --> 02:11:55,559 quickly uh this error interface is 3183 02:11:55,559 --> 02:11:56,920 really just an interface that wraps a 3184 02:11:56,920 --> 02:11:58,800 method returning a string because if you 3185 02:11:58,800 --> 02:12:00,760 think about it at the end of the day an 3186 02:12:00,760 --> 02:12:04,400 error is just a kind of nullable string 3187 02:12:04,400 --> 02:12:06,360 either it's a string representing what 3188 02:12:06,360 --> 02:12:08,679 went wrong or saying what went wrong or 3189 02:12:08,679 --> 02:12:11,199 it's nothing because nothing went wrong 3190 02:12:11,199 --> 02:12:14,679 so being good at handling errors in go 3191 02:12:14,679 --> 02:12:16,679 has a lot to do with being good at 3192 02:12:16,679 --> 02:12:19,320 formatting strings or formatting useful 3193 02:12:19,320 --> 02:12:21,679 error messages so let's review how we 3194 02:12:21,679 --> 02:12:24,280 format strings in go most formatting go 3195 02:12:24,280 --> 02:12:26,639 is built around kind of these formatting 3196 02:12:26,639 --> 02:12:28,920 verbs that are defined in the format 3197 02:12:28,920 --> 02:12:31,079 package the fmt package of the standard 3198 02:12:31,079 --> 02:12:33,840 Library so for example the S printf 3199 02:12:33,840 --> 02:12:35,880 function returns a string where it 3200 02:12:35,880 --> 02:12:38,679 interpolates the values passed into the 3201 02:12:38,679 --> 02:12:41,199 function after the formatting string 3202 02:12:41,199 --> 02:12:43,880 into the formatting string uh string 3203 02:12:43,880 --> 02:12:45,679 where where the verbs exist so for 3204 02:12:45,679 --> 02:12:48,079 example this first percent V is replaced 3205 02:12:48,079 --> 02:12:50,480 with name the second percent V is 3206 02:12:50,480 --> 02:12:53,840 replaced with age percent V is the verb 3207 02:12:53,840 --> 02:12:56,360 we use for sort of the default format 3208 02:12:56,360 --> 02:12:58,280 right if you format an integer using 3209 02:12:58,280 --> 02:13:00,679 percent V then it kind of just prints 3210 02:13:00,679 --> 02:13:03,199 the integer in string form um but there 3211 02:13:03,199 --> 02:13:04,760 are other ways that we can format stuff 3212 02:13:04,760 --> 02:13:07,679 for example the percent F verb is used 3213 02:13:07,679 --> 02:13:10,320 to format floats and you can actually 3214 02:13:10,320 --> 02:13:13,320 specify how many decimal places you want 3215 02:13:13,320 --> 02:13:16,000 to show up in your output string by kind 3216 02:13:16,000 --> 02:13:19,320 of prefixing the F portion with a point 3217 02:13:19,320 --> 02:13:23,159 2 for two decimal places or say A.1 for 3218 02:13:23,159 --> 02:13:25,520 a single decimal place so let's jump 3219 02:13:25,520 --> 02:13:27,440 right into the coding assignment 3220 02:13:27,440 --> 02:13:29,360 assignment says we need better error 3221 02:13:29,360 --> 02:13:30,880 logs for our backend developers to help 3222 02:13:30,880 --> 02:13:33,040 them debug their code complete the get 3223 02:13:33,040 --> 02:13:35,040 SMS error string function so that's this 3224 02:13:35,040 --> 02:13:36,639 one right here um it should return a 3225 02:13:36,639 --> 02:13:38,840 string with this format Okay cool so I'm 3226 02:13:38,840 --> 02:13:41,000 just going to jump right ahead so it 3227 02:13:41,000 --> 02:13:43,360 should 3228 02:13:44,239 --> 02:13:45,880 return 3229 02:13:45,880 --> 02:13:48,800 turn fmts printf right because we're 3230 02:13:48,800 --> 02:13:52,199 trying to format a string uh this format 3231 02:13:52,199 --> 02:13:55,480 let me expand that a little 3232 02:13:56,360 --> 02:13:58,559 bit okay so return a string with that 3233 02:13:58,559 --> 02:14:00,719 format uh cost is the cost of the SMS so 3234 02:14:00,719 --> 02:14:03,719 I'm going to replace cost here with the 3235 02:14:03,719 --> 02:14:06,079 cost formatted to two decimal places so 3236 02:14:06,079 --> 02:14:09,679 percent Point 2 F right for two decimal 3237 02:14:09,679 --> 02:14:12,920 places and replace recipient with the 3238 02:14:12,920 --> 02:14:14,199 stringified representation of the 3239 02:14:14,199 --> 02:14:15,559 recipient's phone number which is the 3240 02:14:15,559 --> 02:14:16,559 string 3241 02:14:16,559 --> 02:14:19,880 here so percent v um it's important to 3242 02:14:19,880 --> 02:14:21,559 point out I could also use S here to 3243 02:14:21,559 --> 02:14:24,000 format a string but V and S do the same 3244 02:14:24,000 --> 02:14:25,960 thing effectively um when you're working 3245 02:14:25,960 --> 02:14:28,079 with 3246 02:14:28,520 --> 02:14:31,040 strings 3247 02:14:31,040 --> 02:14:33,960 and then we need to pass in as 3248 02:14:33,960 --> 02:14:35,960 parameters the values that we want to 3249 02:14:35,960 --> 02:14:37,559 format or that we want to interpolate 3250 02:14:37,559 --> 02:14:39,679 into the string so it's going to be cost 3251 02:14:39,679 --> 02:14:41,679 and 3252 02:14:41,679 --> 02:14:44,040 recipient going to Dent that because 3253 02:14:44,040 --> 02:14:47,199 that is some crazy 3254 02:14:48,480 --> 02:14:51,599 formatting okay that looks better all 3255 02:14:51,599 --> 02:14:54,199 right SMS that costs per point2 F to be 3256 02:14:54,199 --> 02:14:56,719 sent to percent V this looks good to me 3257 02:14:56,719 --> 02:14:57,639 all right I'm going to go ahead and run 3258 02:14:57,639 --> 02:14:59,199 that and see what we 3259 02:14:59,199 --> 02:15:02,960 get ah right can't forget to import the 3260 02:15:02,960 --> 02:15:06,960 formatting package let's run 3261 02:15:06,960 --> 02:15:11,040 that okay SMS that costs 1.40 to be sent 3262 02:15:11,040 --> 02:15:14,079 to the string cannot be 3263 02:15:14,079 --> 02:15:17,119 sent awesome this looks correct to me 3264 02:15:17,119 --> 02:15:19,199 I'm going to go ahead and submit that 3265 02:15:19,199 --> 02:15:21,280 let's talk about building our own cust 3266 02:15:21,280 --> 02:15:24,599 error types so remember the error 3267 02:15:24,599 --> 02:15:26,800 interface is an interface in fact let me 3268 02:15:26,800 --> 02:15:28,639 jump back and show you what it looks 3269 02:15:28,639 --> 02:15:31,320 like again so it's just this interface 3270 02:15:31,320 --> 02:15:33,440 here and because it's an interface that 3271 02:15:33,440 --> 02:15:36,079 means we can build our own types like 3272 02:15:36,079 --> 02:15:38,239 this user error struct here that 3273 02:15:38,239 --> 02:15:40,880 Implement that interface which means 3274 02:15:40,880 --> 02:15:43,920 they can be used as errors and remember 3275 02:15:43,920 --> 02:15:45,920 that the error interface just has one 3276 02:15:45,920 --> 02:15:48,239 single method that we need to Define 3277 02:15:48,239 --> 02:15:50,079 right the error method that returns a 3278 02:15:50,079 --> 02:15:53,280 string and as long as we have that then 3279 02:15:53,280 --> 02:15:56,719 our type can be used as an error so for 3280 02:15:56,719 --> 02:15:58,320 example we could create this user error 3281 02:15:58,320 --> 02:16:01,599 type that stores a name and then we can 3282 02:16:01,599 --> 02:16:04,679 use it as an error to format an error 3283 02:16:04,679 --> 02:16:07,520 message that contains the name of the 3284 02:16:07,520 --> 02:16:10,599 user's account who had an error so for 3285 02:16:10,599 --> 02:16:12,360 example in this snippet here we have a 3286 02:16:12,360 --> 02:16:15,559 send SMS function and if we're not able 3287 02:16:15,559 --> 02:16:17,679 to send a message to a user we can 3288 02:16:17,679 --> 02:16:19,599 actually just return that user error 3289 02:16:19,599 --> 02:16:22,559 struct with the user's name and again 3290 02:16:22,559 --> 02:16:25,360 that is an error we can return that 3291 02:16:25,360 --> 02:16:27,880 struct as an error type because it 3292 02:16:27,880 --> 02:16:30,320 implements the error interface the 3293 02:16:30,320 --> 02:16:31,760 caller of this function would then just 3294 02:16:31,760 --> 02:16:34,559 treat it like any other error the reason 3295 02:16:34,559 --> 02:16:36,880 this is useful is that we can store 3296 02:16:36,880 --> 02:16:39,760 structur data within our errors so if we 3297 02:16:39,760 --> 02:16:42,040 want to format them a specific way we 3298 02:16:42,040 --> 02:16:45,000 have access to sort of dynamic data like 3299 02:16:45,000 --> 02:16:47,519 a name let's write some code that uses 3300 02:16:47,519 --> 02:16:49,599 this concept so the assignment says our 3301 02:16:49,599 --> 02:16:50,920 users are frequently trying to run 3302 02:16:50,920 --> 02:16:52,840 custom analytics queries on their 3303 02:16:52,840 --> 02:16:54,960 message deliverability metrics right so 3304 02:16:54,960 --> 02:16:56,319 we're sending lots of messages we want 3305 02:16:56,319 --> 02:16:58,319 to know are these messages getting 3306 02:16:58,319 --> 02:17:00,479 delivered they end up writing a bad 3307 02:17:00,479 --> 02:17:02,080 query that tries to divide a number by 3308 02:17:02,080 --> 02:17:03,679 zero it's become such a problem that we 3309 02:17:03,679 --> 02:17:04,719 think it would be best to make a 3310 02:17:04,719 --> 02:17:06,920 specific type of error um for dividing 3311 02:17:06,920 --> 02:17:09,280 by zero update the code so that the 3312 02:17:09,280 --> 02:17:12,280 Divide error type so that's this error 3313 02:17:12,280 --> 02:17:15,679 type here or rather this struct here 3314 02:17:15,679 --> 02:17:18,040 implements the error interface its error 3315 02:17:18,040 --> 02:17:19,719 method should return a string formatted 3316 02:17:19,719 --> 02:17:21,880 in the following way cannot divide 3317 02:17:21,880 --> 02:17:24,840 dividend by zero okay let's write that 3318 02:17:24,840 --> 02:17:29,479 method so it's going to be a function on 3319 02:17:29,479 --> 02:17:31,719 the Divide error type so I'm going to 3320 02:17:31,719 --> 02:17:34,479 name it de which is 3321 02:17:34,479 --> 02:17:38,200 a a divide error and the name of the 3322 02:17:38,200 --> 02:17:40,160 function must be error takes no 3323 02:17:40,160 --> 02:17:42,639 arguments and returns a string right so 3324 02:17:42,639 --> 02:17:44,479 that's that's the function signature we 3325 02:17:44,479 --> 02:17:47,479 need to use um to implement the error 3326 02:17:47,479 --> 02:17:49,920 interface and then we're going to return 3327 02:17:49,920 --> 02:17:51,960 a string and we're going to need to 3328 02:17:51,960 --> 02:17:54,080 format the string so we'll use S 3329 02:17:54,080 --> 02:17:58,200 printf uh the format package is already 3330 02:17:58,200 --> 02:18:03,120 imported and this is our template and 3331 02:18:03,120 --> 02:18:06,559 dividend in this case is a float 3332 02:18:06,559 --> 02:18:08,080 64 3333 02:18:08,080 --> 02:18:10,920 and uh you it says here dividend is the 3334 02:18:10,920 --> 02:18:12,679 actual dividend use the percent V verb 3335 02:18:12,679 --> 02:18:14,960 so percent V okay so we're just going to 3336 02:18:14,960 --> 02:18:16,479 kind of do the default formatting for a 3337 02:18:16,479 --> 02:18:17,840 float 3338 02:18:17,840 --> 02:18:21,319 64 and 3339 02:18:21,319 --> 02:18:24,080 let me indent all this so that it's kind 3340 02:18:24,080 --> 02:18:25,639 of 3341 02:18:25,639 --> 02:18:28,120 readable where dividend is the actual 3342 02:18:28,120 --> 02:18:29,559 dividend of the divider okay so we'll do 3343 02:18:29,559 --> 02:18:32,599 de do 3344 02:18:32,599 --> 02:18:36,639 Dividend that will interpolate there 3345 02:18:36,639 --> 02:18:38,719 okay that looks correct to me I think 3346 02:18:38,719 --> 02:18:40,080 we've implemented the error interface 3347 02:18:40,080 --> 02:18:41,719 properly let's go ahead and run 3348 02:18:41,719 --> 02:18:45,319 that uh oh I forgot my 3349 02:18:45,319 --> 02:18:47,719 comma um this is kind of an interesting 3350 02:18:47,719 --> 02:18:50,200 Quirk of the go programming language um 3351 02:18:50,200 --> 02:18:53,280 if you to add a new line after the last 3352 02:18:53,280 --> 02:18:55,439 parameter to a function you have to put 3353 02:18:55,439 --> 02:18:59,000 a comma so this would 3354 02:18:59,000 --> 02:19:01,439 work all right 3355 02:19:01,439 --> 02:19:05,080 and this would 3356 02:19:05,080 --> 02:19:07,639 work but this does not work right that's 3357 02:19:07,639 --> 02:19:08,960 what I did the first time so just kind 3358 02:19:08,960 --> 02:19:11,319 of something to watch out 3359 02:19:11,319 --> 02:19:13,840 for okay so let's take a look at this um 3360 02:19:13,840 --> 02:19:16,599 dividing 10 by 0 cannot divide 10 by 0 3361 02:19:16,599 --> 02:19:19,319 dividing 10 by 2 quotient 5 dividing 15 3362 02:19:19,319 --> 02:19:22,599 by 30 5 question okay this is looking 3363 02:19:22,599 --> 02:19:24,880 like it formatted properly let's submit 3364 02:19:24,880 --> 02:19:26,559 that so we've got a quiz question it 3365 02:19:26,559 --> 02:19:28,519 says what is the underlying type of an 3366 02:19:28,519 --> 02:19:31,240 error is it an interface is it a struct 3367 02:19:31,240 --> 02:19:35,280 is it a string well it could technically 3368 02:19:35,280 --> 02:19:37,240 be a struct or a string right like we 3369 02:19:37,240 --> 02:19:40,319 saw in the last uh the last assignment 3370 02:19:40,319 --> 02:19:42,679 but the most correct thing would be to 3371 02:19:42,679 --> 02:19:43,760 say an 3372 02:19:43,760 --> 02:19:46,840 interface because it must always be an 3373 02:19:46,840 --> 02:19:48,640 interface right it must always implement 3374 02:19:48,640 --> 02:19:50,800 the error interface it could also be a 3375 02:19:50,800 --> 02:19:53,240 struct or a string um but it will always 3376 02:19:53,240 --> 02:19:55,280 be an interface next question is can a 3377 02:19:55,280 --> 02:19:57,520 Type be an error and also fulfill 3378 02:19:57,520 --> 02:20:00,160 another interface well errors are just 3379 02:20:00,160 --> 02:20:01,840 interfaces and we know that types can 3380 02:20:01,840 --> 02:20:03,600 fulfill any number of interfaces as long 3381 02:20:03,600 --> 02:20:05,920 as they have all of the required methods 3382 02:20:05,920 --> 02:20:08,600 so yeah there's no problem with this 3383 02:20:08,600 --> 02:20:11,479 let's talk about the errors package so 3384 02:20:11,479 --> 02:20:13,080 the standard library and go has an 3385 02:20:13,080 --> 02:20:16,479 errors package that exposes a few useful 3386 02:20:16,479 --> 02:20:17,880 functionalities but the one we're most 3387 02:20:17,880 --> 02:20:20,319 interested in right now is the errors. 3388 02:20:20,319 --> 02:20:22,600 new function so the useful thing about 3389 02:20:22,600 --> 02:20:24,880 the errors. new function is allows us to 3390 02:20:24,880 --> 02:20:27,680 create a new error from just a string so 3391 02:20:27,680 --> 02:20:29,479 we don't need to kind of you know Define 3392 02:20:29,479 --> 02:20:31,560 a new struct or a new type and then have 3393 02:20:31,560 --> 02:20:34,319 it explicitly implement the error 3394 02:20:34,319 --> 02:20:36,479 interface that can be a lot of code if 3395 02:20:36,479 --> 02:20:39,120 all we want to do is kind of return an 3396 02:20:39,120 --> 02:20:41,600 error with a very specific string let's 3397 02:20:41,600 --> 02:20:43,160 go ahead and use it the assignment says 3398 02:20:43,160 --> 02:20:45,120 twilio software Architects may have over 3399 02:20:45,120 --> 02:20:46,319 complicated the requirements from the 3400 02:20:46,319 --> 02:20:48,600 last coding assignment yeah all we 3401 02:20:48,600 --> 02:20:50,160 needed was a new generic error message 3402 02:20:50,160 --> 02:20:52,280 that returns a string no dividing by 3403 02:20:52,280 --> 02:20:54,080 zero when a user attempts to get us to 3404 02:20:54,080 --> 02:20:56,120 perform the taboo right the taboo of 3405 02:20:56,120 --> 02:20:58,399 dividing something by zero complete the 3406 02:20:58,399 --> 02:21:00,560 divide function use the errors. new 3407 02:21:00,560 --> 02:21:02,479 function to create an error when y 3408 02:21:02,479 --> 02:21:04,840 equals z that reads no dividing by zero 3409 02:21:04,840 --> 02:21:06,880 okay so this is pretty straightforward 3410 02:21:06,880 --> 02:21:09,720 basically if Y is zero which means that 3411 02:21:09,720 --> 02:21:12,200 the the number that we divide by would 3412 02:21:12,200 --> 02:21:13,720 be zero which is obviously a huge 3413 02:21:13,720 --> 02:21:15,040 problem in mathematics you're not 3414 02:21:15,040 --> 02:21:16,920 allowed to do that in go or most 3415 02:21:16,920 --> 02:21:19,000 programming languages that I'm aware of 3416 02:21:19,000 --> 02:21:21,560 um so we need to return an error here uh 3417 02:21:21,560 --> 02:21:23,800 so that this operation never happens so 3418 02:21:23,800 --> 02:21:26,920 we'll return errors. new looks like the 3419 02:21:26,920 --> 02:21:29,720 errors package is already imported for 3420 02:21:29,720 --> 02:21:33,040 us and we just need to return an 3421 02:21:33,040 --> 02:21:37,520 error that says no dividing by 3422 02:21:37,520 --> 02:21:39,560 zero okay let's go ahead and run that 3423 02:21:39,560 --> 02:21:40,760 and see what we 3424 02:21:40,760 --> 02:21:44,439 get oh I screwed up this function 3425 02:21:44,439 --> 02:21:47,720 returns a float 64 and an error so we 3426 02:21:47,720 --> 02:21:50,280 should return a zero value for that 3427 02:21:50,280 --> 02:21:52,160 first value when we're returning a 3428 02:21:52,160 --> 02:21:54,880 non-nil error let's go ahead and run 3429 02:21:54,880 --> 02:21:58,160 that cool dividing 10 by Z no dividing 3430 02:21:58,160 --> 02:22:00,280 by 3431 02:22:00,520 --> 02:22:03,319 Z all of this looks good to me let's 3432 02:22:03,319 --> 02:22:05,960 talk about loops in go so if you are 3433 02:22:05,960 --> 02:22:07,439 familiar with Loops in other languages 3434 02:22:07,439 --> 02:22:09,160 Loops in go syntactically are very 3435 02:22:09,160 --> 02:22:11,479 similar to say Loops in JavaScript uh 3436 02:22:11,479 --> 02:22:12,760 the main difference is just that we 3437 02:22:12,760 --> 02:22:16,080 don't use the parentheses around uh kind 3438 02:22:16,080 --> 02:22:19,560 of the the signature of the for Loop um 3439 02:22:19,560 --> 02:22:21,000 which again is very similar to how if 3440 02:22:21,000 --> 02:22:22,840 statements in go work we're basically 3441 02:22:22,840 --> 02:22:25,280 just dropping those uh parentheses 3442 02:22:25,280 --> 02:22:27,560 syntactically um the initial portion 3443 02:22:27,560 --> 02:22:29,359 runs at the beginning so for example in 3444 02:22:29,359 --> 02:22:31,120 this uh snippet of code where We're 3445 02:22:31,120 --> 02:22:34,640 looping over the integers 0 through 9 UM 3446 02:22:34,640 --> 02:22:36,120 in the initial section we're just 3447 02:22:36,120 --> 02:22:38,080 initializing a variable I and setting it 3448 02:22:38,080 --> 02:22:40,960 equal to zero um in the condition 3449 02:22:40,960 --> 02:22:42,840 section uh we're checking and making 3450 02:22:42,840 --> 02:22:44,920 sure that I is less than 10 so at the 3451 02:22:44,920 --> 02:22:47,680 end of every uh kind of iteration of the 3452 02:22:47,680 --> 02:22:49,319 body which in this case we're just 3453 02:22:49,319 --> 02:22:52,000 printing I in the body um we're going to 3454 02:22:52,000 --> 02:22:53,439 check and make sure that I is less than 3455 02:22:53,439 --> 02:22:55,720 10 if it is we'll continue on to the 3456 02:22:55,720 --> 02:22:57,040 next iteration of the loop otherwise 3457 02:22:57,040 --> 02:23:00,240 we'll be done um and then at the end of 3458 02:23:00,240 --> 02:23:01,920 every iteration we'll also be running 3459 02:23:01,920 --> 02:23:04,240 this after section so we'll be 3460 02:23:04,240 --> 02:23:07,000 incrementing I and that happens before 3461 02:23:07,000 --> 02:23:10,160 uh the condition is run so for example 3462 02:23:10,160 --> 02:23:13,800 if we increment I to 10 and then I is no 3463 02:23:13,800 --> 02:23:15,960 longer less than 10 we will not continue 3464 02:23:15,960 --> 02:23:17,640 on to the next iteration of loop which 3465 02:23:17,640 --> 02:23:20,160 is why this prints 0 through 9 and not 0 3466 02:23:20,160 --> 02:23:21,720 through 10 10 let's jump right into the 3467 02:23:21,720 --> 02:23:23,479 assignment says at texo we have a 3468 02:23:23,479 --> 02:23:25,200 dynamic formula for determining how much 3469 02:23:25,200 --> 02:23:28,160 a batch of bulk messages cost to send so 3470 02:23:28,160 --> 02:23:29,720 we need to complete the bulk send 3471 02:23:29,720 --> 02:23:31,279 function it takes a number of messages 3472 02:23:31,279 --> 02:23:33,960 as input and returns a float 64 um which 3473 02:23:33,960 --> 02:23:36,840 it looks like will be the total cost of 3474 02:23:36,840 --> 02:23:40,319 the batch of messages okay each message 3475 02:23:40,319 --> 02:23:43,359 costs 1.0 plus an additional fee the fee 3476 02:23:43,359 --> 02:23:45,040 structure is so it's going to be first 3477 02:23:45,040 --> 02:23:49,040 message is 1.0 plus 0 so 0 is the fee 3478 02:23:49,040 --> 02:23:51,200 second message is 1.0 Plus 3479 02:23:51,200 --> 02:23:54,880 01 third message is 1.0 plus 02 okay 3480 02:23:54,880 --> 02:23:56,640 cool and then our job is to use a loop 3481 02:23:56,640 --> 02:23:59,080 to calculate the total cost of all of 3482 02:23:59,080 --> 02:24:01,279 these messages for you know the number 3483 02:24:01,279 --> 02:24:03,960 of messages that we've been given okay 3484 02:24:03,960 --> 02:24:05,680 let's let's just start writing some code 3485 02:24:05,680 --> 02:24:07,960 so total cost I'm going to just start it 3486 02:24:07,960 --> 02:24:11,200 out at 0.0 and then we'll use a loop or 3487 02:24:11,200 --> 02:24:15,160 I equals 0 uh to do like num messages 3488 02:24:15,160 --> 02:24:17,479 iterations so you know a number of 3489 02:24:17,479 --> 02:24:20,080 iterations equal to num messages so um 3490 02:24:20,080 --> 02:24:22,479 start I at zero uh and then we'll do I 3491 02:24:22,479 --> 02:24:23,720 is less 3492 02:24:23,720 --> 02:24:26,720 than n 3493 02:24:26,720 --> 02:24:29,279 messages and I 3494 02:24:29,279 --> 02:24:32,560 Plus+ okay so this uh kind of body of 3495 02:24:32,560 --> 02:24:34,080 the for Loop should execute numb 3496 02:24:34,080 --> 02:24:36,920 messages times and we're going to want 3497 02:24:36,920 --> 02:24:39,920 to add the total cost so plus equals um 3498 02:24:39,920 --> 02:24:41,040 and we're going to use this formula so 3499 02:24:41,040 --> 02:24:43,399 it's going to be 1.0 3500 02:24:43,399 --> 02:24:45,840 plus this fee and how do we calculate 3501 02:24:45,840 --> 02:24:49,080 that fee well it looks to me like it is 3502 02:24:49,080 --> 02:24:51,279 0.01 3503 02:24:51,279 --> 02:24:55,560 times the basically the message number 3504 02:24:55,560 --> 02:24:58,479 right so for the first message at index0 3505 02:24:58,479 --> 02:25:00,840 I equals 0 um it's going to be a fee of 3506 02:25:00,840 --> 02:25:03,399 zero so if we just use I this should 3507 02:25:03,399 --> 02:25:04,760 work because if I is zero and we 3508 02:25:04,760 --> 02:25:07,439 multiply that by 01 anything multiplied 3509 02:25:07,439 --> 02:25:11,560 by 0 is 0 right so we'd get 1.0 + 0 for 3510 02:25:11,560 --> 02:25:13,359 the second message I should be one so 3511 02:25:13,359 --> 02:25:15,760 we'll get 1 plus 01 because anything 3512 02:25:15,760 --> 02:25:18,560 multiplied by one is itself um and so on 3513 02:25:18,560 --> 02:25:20,319 and so forth um that's looking correct 3514 02:25:20,319 --> 02:25:22,439 to me at the end of the function we'll 3515 02:25:22,439 --> 02:25:24,760 just return a total 3516 02:25:24,760 --> 02:25:29,800 cost cool let's run that oh untyped 3517 02:25:29,800 --> 02:25:31,800 float constant truncated to int okay so 3518 02:25:31,800 --> 02:25:34,800 I is an INT and we cannot multiply an 3519 02:25:34,800 --> 02:25:38,000 INT by a float 64 so I'm going to cast 3520 02:25:38,000 --> 02:25:41,680 um I to a float 64 let's try that 3521 02:25:41,680 --> 02:25:43,720 again and take a look at some of these 3522 02:25:43,720 --> 02:25:46,399 numbers Okay cool so the cost for 10 3523 02:25:46,399 --> 02:25:49,080 messages is 3524 02:25:49,080 --> 02:25:52,600 10.45 and and that sounds about right 3525 02:25:52,600 --> 02:25:54,760 right because each message costs 3526 02:25:54,760 --> 02:25:57,800 one plus this like fractional part that 3527 02:25:57,800 --> 02:25:59,880 grows over time so like the 10th message 3528 02:25:59,880 --> 02:26:03,080 would have cost like 3529 02:26:03,080 --> 02:26:06,880 0.10 and it would decrease over time so 3530 02:26:06,880 --> 02:26:10,720 that looks about right to 3531 02:26:12,000 --> 02:26:14,720 me 50 3532 02:26:14,720 --> 02:26:16,960 messages yep okay I'm going to go ahead 3533 02:26:16,960 --> 02:26:18,880 and submit that one interesting thing 3534 02:26:18,880 --> 02:26:21,319 about four Loops in go is that each 3535 02:26:21,319 --> 02:26:23,399 section of the for Loop the initial the 3536 02:26:23,399 --> 02:26:25,160 condition and the after are actually 3537 02:26:25,160 --> 02:26:27,479 optional and we can omit any of them so 3538 02:26:27,479 --> 02:26:30,000 for example if we omit the condition 3539 02:26:30,000 --> 02:26:32,279 then the for Loop will just run forever 3540 02:26:32,279 --> 02:26:34,240 so let's see why this might be useful um 3541 02:26:34,240 --> 02:26:35,920 let's jump into the assignment the 3542 02:26:35,920 --> 02:26:37,279 assignment says complete the max 3543 02:26:37,279 --> 02:26:39,160 messages function given a cost threshold 3544 02:26:39,160 --> 02:26:40,359 it should calculate the maximum number 3545 02:26:40,359 --> 02:26:42,000 of messages that can be sent um and then 3546 02:26:42,000 --> 02:26:44,160 it looks like the fees for each message 3547 02:26:44,160 --> 02:26:45,439 are going to be identical to the last 3548 02:26:45,439 --> 02:26:47,439 assignment so let's go ahead and just 3549 02:26:47,439 --> 02:26:49,760 get started um so max messages we have a 3550 02:26:49,760 --> 02:26:51,800 threshold a cost threshold right we want 3551 02:26:51,800 --> 02:26:54,960 to see how many messages we can send 3552 02:26:54,960 --> 02:26:56,520 while keeping the total cost under the 3553 02:26:56,520 --> 02:26:58,359 threshold so I'm going to create a total 3554 02:26:58,359 --> 02:27:01,680 cost variable and set it equal to 3555 02:27:01,680 --> 02:27:03,520 0.0 and then this is going to look 3556 02:27:03,520 --> 02:27:05,880 really similar to the last assignment um 3557 02:27:05,880 --> 02:27:08,120 but basically we'll set I equal to zero 3558 02:27:08,120 --> 02:27:09,439 to 3559 02:27:09,439 --> 02:27:13,200 start um I'll skip the condition for now 3560 02:27:13,200 --> 02:27:15,560 because we don't know to what number 3561 02:27:15,560 --> 02:27:17,800 we're kind of looping up to right we're 3562 02:27:17,800 --> 02:27:19,840 trying to calculate that so I don't know 3563 02:27:19,840 --> 02:27:23,359 where stop yet um but I do want to 3564 02:27:23,359 --> 02:27:25,840 increment I with every uh iteration of 3565 02:27:25,840 --> 02:27:26,520 the 3566 02:27:26,520 --> 02:27:29,080 loop and then I basically want to um 3567 02:27:29,080 --> 02:27:31,760 update the total cost by adding to it um 3568 02:27:31,760 --> 02:27:34,359 and use uh this formula over here right 3569 02:27:34,359 --> 02:27:36,640 so it's going to be 3570 02:27:36,640 --> 02:27:39,600 1.0 plus 3571 02:27:39,600 --> 02:27:41,279 0.01 3572 02:27:41,279 --> 02:27:46,399 time time I which I need to cast with 3573 02:27:46,399 --> 02:27:49,080 64 okay so that formula is looking again 3574 02:27:49,080 --> 02:27:50,680 identical last time 3575 02:27:50,680 --> 02:27:52,880 now if I want to 3576 02:27:52,880 --> 02:27:55,920 return the the maximum messages that I 3577 02:27:55,920 --> 02:27:57,800 can send while keeping the cost under 3578 02:27:57,800 --> 02:28:00,560 the threshold then basically I need to 3579 02:28:00,560 --> 02:28:04,160 check and say if the total cost is 3580 02:28:04,160 --> 02:28:06,279 greater than the 3581 02:28:06,279 --> 02:28:10,040 threshold then I should return 3582 02:28:10,040 --> 02:28:13,040 IES that sound right so for example 3583 02:28:13,040 --> 02:28:15,439 let's say that right off the bat the 3584 02:28:15,439 --> 02:28:17,680 threshold were I don't know is it 3585 02:28:17,680 --> 02:28:20,000 negative one right so I'm not allowed to 3586 02:28:20,000 --> 02:28:21,399 say send anything I would want to in 3587 02:28:21,399 --> 02:28:23,120 that case return zero right cuz I can't 3588 02:28:23,120 --> 02:28:25,240 send any messages so what would happen 3589 02:28:25,240 --> 02:28:27,319 we'd enter the loop I'd calculate the 3590 02:28:27,319 --> 02:28:29,000 total cost for the first message which 3591 02:28:29,000 --> 02:28:29,840 would be 3592 02:28:29,840 --> 02:28:32,800 1.0 and then because the total cost is 3593 02:28:32,800 --> 02:28:34,040 already higher than the threshold I 3594 02:28:34,040 --> 02:28:36,279 would return I which would be zero so 3595 02:28:36,279 --> 02:28:39,120 that works right however if the 3596 02:28:39,120 --> 02:28:40,240 threshold were a little higher let's say 3597 02:28:40,240 --> 02:28:42,920 the threshold were 1.5 uh then what 3598 02:28:42,920 --> 02:28:45,319 would happen is we do that comparison 3599 02:28:45,319 --> 02:28:49,640 the total cost would be less than the 3600 02:28:49,640 --> 02:28:50,640 threshold 3601 02:28:50,640 --> 02:28:52,240 so we'd continue to the next Loop uh 3602 02:28:52,240 --> 02:28:53,920 iteration of the loop where I would be 3603 02:28:53,920 --> 02:28:56,319 incremented to one and then on that next 3604 02:28:56,319 --> 02:28:57,880 iteration we'd go over okay so this is 3605 02:28:57,880 --> 02:28:59,720 looking good to me let me go ahead and 3606 02:28:59,720 --> 02:29:02,279 run this 3607 02:29:04,200 --> 02:29:08,560 code okay so with a threshold of 10 I 3608 02:29:08,560 --> 02:29:10,439 can send nine messages without going 3609 02:29:10,439 --> 02:29:11,960 over the 3610 02:29:11,960 --> 02:29:16,080 threshold that sounds right right 3611 02:29:16,080 --> 02:29:17,399 because I'd have like nine in some 3612 02:29:17,399 --> 02:29:18,439 fractional 3613 02:29:18,439 --> 02:29:21,640 part let's go ahead and mcy most 3614 02:29:21,640 --> 02:29:23,680 programming languages have support for a 3615 02:29:23,680 --> 02:29:26,720 while loop and really a while loop is 3616 02:29:26,720 --> 02:29:29,080 very similar to a four Loop except it 3617 02:29:29,080 --> 02:29:31,560 doesn't have that kind of initial and 3618 02:29:31,560 --> 02:29:34,800 after statement it it just runs until 3619 02:29:34,800 --> 02:29:38,160 some condition is no longer true now 3620 02:29:38,160 --> 02:29:40,120 because of this similarity the authors 3621 02:29:40,120 --> 02:29:41,880 of the go programming language decided 3622 02:29:41,880 --> 02:29:45,120 to not include an explicit while loop 3623 02:29:45,120 --> 02:29:48,120 with a while keyword instead the for 3624 02:29:48,120 --> 02:29:51,319 Loop is a while loop or just basically 3625 02:29:51,319 --> 02:29:54,560 both those side um kind of sections are 3626 02:29:54,560 --> 02:29:57,600 omitted and we just have a condition 3627 02:29:57,600 --> 02:29:59,560 that follows the four keyword so in 3628 02:29:59,560 --> 02:30:01,640 other words if we have a four keyword 3629 02:30:01,640 --> 02:30:03,920 and then a single expression then it is 3630 02:30:03,920 --> 02:30:07,240 a condition um that while true will 3631 02:30:07,240 --> 02:30:09,840 continue to kind of run the body of the 3632 02:30:09,840 --> 02:30:12,080 loop over and over and over again until 3633 02:30:12,080 --> 02:30:14,520 the condition stops being true let's 3634 02:30:14,520 --> 02:30:17,160 take a look at an example um here we 3635 02:30:17,160 --> 02:30:20,040 have a variable called plant height we 3636 02:30:20,040 --> 02:30:21,960 start it uh equal to one and we've done 3637 02:30:21,960 --> 02:30:24,279 this outside of the for Loop right and 3638 02:30:24,279 --> 02:30:25,840 then within the for Loop we just have 3639 02:30:25,840 --> 02:30:27,680 one section where we're comparing the 3640 02:30:27,680 --> 02:30:30,399 variable plant height to the number five 3641 02:30:30,399 --> 02:30:32,840 right and while it is less than five 3642 02:30:32,840 --> 02:30:34,479 we'll print this message and then at the 3643 02:30:34,479 --> 02:30:36,000 end of the loop we'll increment plant 3644 02:30:36,000 --> 02:30:38,160 height now you might notice this looks 3645 02:30:38,160 --> 02:30:39,279 just like a for Loop where we've 3646 02:30:39,279 --> 02:30:40,600 essentially taken the initial statement 3647 02:30:40,600 --> 02:30:42,439 and moved it up outside of the for Loop 3648 02:30:42,439 --> 02:30:44,319 body and we've taken the after statement 3649 02:30:44,319 --> 02:30:45,840 and moved it within the for Loop body 3650 02:30:45,840 --> 02:30:48,240 and that is what we've done right but 3651 02:30:48,240 --> 02:30:51,520 it's to demonstrate that this is valid 3652 02:30:51,520 --> 02:30:54,000 syntax let's jump right into the 3653 02:30:54,000 --> 02:30:56,279 assignment okay so the assignment says 3654 02:30:56,279 --> 02:30:57,240 we have an interesting new cost 3655 02:30:57,240 --> 02:31:00,120 structure for our SMS vendor so at texo 3656 02:31:00,120 --> 02:31:02,279 we have a vendor that we have to pay to 3657 02:31:02,279 --> 02:31:04,319 send text messages through right so 3658 02:31:04,319 --> 02:31:05,960 we're a software service that makes 3659 02:31:05,960 --> 02:31:07,960 sending text messages easy but we do 3660 02:31:07,960 --> 02:31:10,520 have to pay some kind of uh maybe 3661 02:31:10,520 --> 02:31:12,160 Hardware service that actually does the 3662 02:31:12,160 --> 02:31:15,040 sending of uh the text messages kind of 3663 02:31:15,040 --> 02:31:17,800 over the wireless network okay um they 3664 02:31:17,800 --> 02:31:19,319 charge exponentially more money for each 3665 02:31:19,319 --> 02:31:21,560 consecutive test text we send let's 3666 02:31:21,560 --> 02:31:22,720 write a function that can calculate how 3667 02:31:22,720 --> 02:31:24,200 many messages we can send in a given 3668 02:31:24,200 --> 02:31:26,200 batch uh given a cost multiplier and a 3669 02:31:26,200 --> 02:31:28,960 Max cost in pennies okay so given a cost 3670 02:31:28,960 --> 02:31:31,479 multiplier and a maximum cost our 3671 02:31:31,479 --> 02:31:33,680 function will return basically the 3672 02:31:33,680 --> 02:31:35,160 number of messages that we're allowed to 3673 02:31:35,160 --> 02:31:39,399 send um that's under that that Max cost 3674 02:31:39,399 --> 02:31:40,960 so it says in a nutshell the first 3675 02:31:40,960 --> 02:31:43,319 message costs one penny Okay actual cost 3676 02:31:43,319 --> 02:31:45,080 and pennies starts at one and each 3677 02:31:45,080 --> 02:31:47,200 message after that first message uh 3678 02:31:47,200 --> 02:31:49,439 costs the same as the previous message 3679 02:31:49,439 --> 02:31:52,840 multip by the cost multiplier okay so 3680 02:31:52,840 --> 02:31:55,920 that's happening here um gets expensive 3681 02:31:55,920 --> 02:31:57,840 uh there is an infinite Loop in the code 3682 02:31:57,840 --> 02:32:00,200 okay so on line 10 here we have this 3683 02:32:00,200 --> 02:32:03,040 four with no body and then an open curly 3684 02:32:03,040 --> 02:32:05,319 bracket um let me show you what happens 3685 02:32:05,319 --> 02:32:07,640 when we run that our codee's going to 3686 02:32:07,640 --> 02:32:10,200 sit and run and execute the body of that 3687 02:32:10,200 --> 02:32:12,000 for Loop over and over and over and over 3688 02:32:12,000 --> 02:32:14,080 with no exit condition uh this is 3689 02:32:14,080 --> 02:32:16,279 obviously a problem we don't want uh an 3690 02:32:16,279 --> 02:32:20,080 infinite for Loop there so our job is to 3691 02:32:20,080 --> 02:32:22,640 exit before incrementing Max messages to 3692 02:32:22,640 --> 02:32:24,359 send if the cost of the next message 3693 02:32:24,359 --> 02:32:26,279 would go over the Max cost so all we 3694 02:32:26,279 --> 02:32:29,920 need to do is check and only execute 3695 02:32:29,920 --> 02:32:33,080 this Loop while the actual cost is less 3696 02:32:33,080 --> 02:32:36,920 than or equal to the Max cost in 3697 02:32:36,920 --> 02:32:38,880 pennies um and we're going to have to 3698 02:32:38,880 --> 02:32:40,840 cast looks like so this is a float this 3699 02:32:40,840 --> 02:32:42,960 is an inch so we're going to cast this 3700 02:32:42,960 --> 02:32:45,960 to 3701 02:32:46,880 --> 02:32:49,479 64 now this should work because Max 3702 02:32:49,479 --> 02:32:51,960 message to send starts at 3703 02:32:51,960 --> 02:32:57,399 zero so assuming the actual cost is less 3704 02:32:57,399 --> 02:32:59,560 than the Max cost then we go ahead and 3705 02:32:59,560 --> 02:33:01,479 increment say we can send one more 3706 02:33:01,479 --> 02:33:03,600 message and then we take a look at the 3707 02:33:03,600 --> 02:33:08,160 next cost and if the next cost is still 3708 02:33:08,160 --> 02:33:10,439 less then we'll essentially get to add 3709 02:33:10,439 --> 02:33:12,080 another message so we'll keep kind of 3710 02:33:12,080 --> 02:33:14,880 looking ahead and calculating the next 3711 02:33:14,880 --> 02:33:17,720 cost right and as soon as the next cost 3712 02:33:17,720 --> 02:33:20,399 goes too high we stop okay so I'm going 3713 02:33:20,399 --> 02:33:23,000 to go ahead and run 3714 02:33:23,240 --> 02:33:28,080 that cool so with a multiplier of 3715 02:33:28,479 --> 02:33:31,840 1.1 and a Max cost of five we can send 3716 02:33:31,840 --> 02:33:34,319 17 messages that sounds about 3717 02:33:34,319 --> 02:33:38,840 right right the actual cost starts at 3718 02:33:39,160 --> 02:33:42,399 one the Max cost is five multiplier of 3719 02:33:42,399 --> 02:33:44,680 1.1 yeah that sounds right um so the 3720 02:33:44,680 --> 02:33:47,720 multiplier goes up Max cost goes up now 3721 02:33:47,720 --> 02:33:50,399 we can send nine messages that all looks 3722 02:33:50,399 --> 02:33:53,240 good to me let's talk about the modulo 3723 02:33:53,240 --> 02:33:55,200 operator how it works and go and kind of 3724 02:33:55,200 --> 02:33:58,920 how it works uh generally so the modulo 3725 02:33:58,920 --> 02:34:01,520 operator is a percent sign so it looks 3726 02:34:01,520 --> 02:34:05,080 like this right and the modulo operator 3727 02:34:05,080 --> 02:34:07,640 essentially calculates 3728 02:34:07,640 --> 02:34:10,279 remainders remainders so what do I mean 3729 02:34:10,279 --> 02:34:12,880 by that well let's jump into an example 3730 02:34:12,880 --> 02:34:16,720 uh let me switch colors so 3731 02:34:16,720 --> 02:34:21,680 four 4 / 3 in sort of a normal uh 3732 02:34:21,680 --> 02:34:26,319 floating Point division uh equals like 3733 02:34:26,319 --> 02:34:28,840 1.33333 forever right um we have this 3734 02:34:28,840 --> 02:34:31,800 fractional part however that's how math 3735 02:34:31,800 --> 02:34:33,359 Works normally and that's how math Works 3736 02:34:33,359 --> 02:34:35,279 in floating Point division in a language 3737 02:34:35,279 --> 02:34:38,040 like go if we're doing integer division 3738 02:34:38,040 --> 02:34:39,720 then we can't have a floating Point 3739 02:34:39,720 --> 02:34:43,160 result so the result of four divided 3 3740 02:34:43,160 --> 02:34:45,080 and integer division is actually just 3741 02:34:45,080 --> 02:34:48,160 one it's essentially the number of times 3742 02:34:48,160 --> 02:34:50,760 that three can be divided evenly into 3743 02:34:50,760 --> 02:34:54,040 four and then we chop off the remainder 3744 02:34:54,040 --> 02:34:57,760 the interesting thing about the modulo 3745 02:34:57,760 --> 02:35:02,520 operator is that 4 modulo 3 doesn't 3746 02:35:02,520 --> 02:35:03,840 return the number of times that three 3747 02:35:03,840 --> 02:35:06,640 can be divided evenly into four it 3748 02:35:06,640 --> 02:35:08,399 Returns the 3749 02:35:08,399 --> 02:35:11,080 remainder after that division so 3750 02:35:11,080 --> 02:35:13,160 actually in the case of Four modulo 3 3751 02:35:13,160 --> 02:35:15,479 the remainder is also one so it's the 3752 02:35:15,479 --> 02:35:21,640 same but for example five modulo 3 3753 02:35:21,640 --> 02:35:22,560 is 3754 02:35:22,560 --> 02:35:27,240 two and 6 modulo 3755 02:35:27,240 --> 02:35:30,920 3 is zero again because three divides 3756 02:35:30,920 --> 02:35:36,080 evenly into six right six integer 3757 02:35:36,080 --> 02:35:39,840 division by three is two right because 3758 02:35:39,840 --> 02:35:43,000 three goes evenly into six twice but the 3759 02:35:43,000 --> 02:35:45,960 remainder is zero that's why 6 mod 3 is 3760 02:35:45,960 --> 02:35:47,840 zero let's just do a couple more 3761 02:35:47,840 --> 02:35:50,120 examples feel free to pause the video um 3762 02:35:50,120 --> 02:35:52,880 in between when I give the question and 3763 02:35:52,880 --> 02:35:54,560 provide the solution um so that maybe 3764 02:35:54,560 --> 02:35:56,880 you can practice a little bit okay so 3765 02:35:56,880 --> 02:35:58,640 let's do 3766 02:35:58,640 --> 02:36:01,960 12 mod 3767 02:36:01,960 --> 02:36:04,560 4 we'll do in fact maybe I'll just write 3768 02:36:04,560 --> 02:36:07,560 out all the problems first let's do 3769 02:36:07,560 --> 02:36:10,000 16 mod 3770 02:36:10,000 --> 02:36:11,880 5 let's 3771 02:36:11,880 --> 02:36:14,359 do 3772 02:36:14,359 --> 02:36:17,840 22 mod 3773 02:36:18,120 --> 02:36:22,560 8 and let's let's do 3774 02:36:22,560 --> 02:36:24,479 27 3775 02:36:24,479 --> 02:36:26,080 mod 3776 02:36:26,080 --> 02:36:29,240 6 I think those will be those will be 3777 02:36:29,240 --> 02:36:31,680 good okay 12 mod four so does four 3778 02:36:31,680 --> 02:36:35,240 divide evenly is 12 uh yes 4 * 3 is 12 3779 02:36:35,240 --> 02:36:37,000 right so the remainder is 3780 02:36:37,000 --> 02:36:39,560 zero all right how many times does five 3781 02:36:39,560 --> 02:36:41,760 divide evenly into 16 the answer is 3782 02:36:41,760 --> 02:36:43,760 three right 5 10 3783 02:36:43,760 --> 02:36:47,000 15 and the remainder would then be one 3784 02:36:47,000 --> 02:36:51,080 how many times does 8 go into 22 8 16 24 3785 02:36:51,080 --> 02:36:53,160 so 24 doesn't work so it's going to be 3786 02:36:53,160 --> 02:36:57,600 16 and then 22 subtract 16 is 6 is the 3787 02:36:57,600 --> 02:37:01,200 remainder right and then 27 mod 6 um 6 3788 02:37:01,200 --> 02:37:05,040 goes into 27 four times 6 * 4 is 24 so a 3789 02:37:05,040 --> 02:37:07,800 remainder of three so an important thing 3790 02:37:07,800 --> 02:37:09,840 to note here is if you're trying to 3791 02:37:09,840 --> 02:37:12,200 figure out if a number divides evenly 3792 02:37:12,200 --> 02:37:14,200 into another number then you can just 3793 02:37:14,200 --> 02:37:20,680 check if say a mod b 3794 02:37:20,680 --> 02:37:26,319 equals 0 right if aod B equals z then 3795 02:37:26,319 --> 02:37:29,399 that means B divides into a an even 3796 02:37:29,399 --> 02:37:33,080 number of times so a is a multiple of B 3797 02:37:33,080 --> 02:37:35,800 so in go the module operator is just 3798 02:37:35,800 --> 02:37:39,120 that percent sign right so seven mod 3 3799 02:37:39,120 --> 02:37:41,319 um this expression is going to evaluate 3800 02:37:41,319 --> 02:37:43,479 to one we'll also need to know about the 3801 02:37:43,479 --> 02:37:45,600 logical and operator and the logical or 3802 02:37:45,600 --> 02:37:47,720 operator which are double Ampersand and 3803 02:37:47,720 --> 02:37:50,680 double bar uh respective The Logical and 3804 02:37:50,680 --> 02:37:53,399 operator operates on two Boolean values 3805 02:37:53,399 --> 02:37:57,080 and only returns true if both sides are 3806 02:37:57,080 --> 02:38:01,720 true right this and that the or Operator 3807 02:38:01,720 --> 02:38:05,359 just needs at least one side to be true 3808 02:38:05,359 --> 02:38:07,359 right in order for the entire expression 3809 02:38:07,359 --> 02:38:09,600 to evaluate to True let's jump into the 3810 02:38:09,600 --> 02:38:10,800 assignment it says we're hiring 3811 02:38:10,800 --> 02:38:12,439 engineers at texo so it's time to brush 3812 02:38:12,439 --> 02:38:14,319 up on the classic fizzbuzz game coding 3813 02:38:14,319 --> 02:38:15,439 exercises have been dramatically 3814 02:38:15,439 --> 02:38:17,240 overused in coding interviews around the 3815 02:38:17,240 --> 02:38:19,080 world complete the fizzbuzz function 3816 02:38:19,080 --> 02:38:20,600 that print the numbers 1 to 100 3817 02:38:20,600 --> 02:38:22,439 inclusive each on their own line but 3818 02:38:22,439 --> 02:38:23,800 substitutes multiples of three for the 3819 02:38:23,800 --> 02:38:25,840 text Fizz multiples of five for Buzz and 3820 02:38:25,840 --> 02:38:29,800 multiples of three and five for fizzbuzz 3821 02:38:29,800 --> 02:38:34,359 okay so we need a for Loop for I colon 3822 02:38:34,359 --> 02:38:38,000 equals 0 I is less than 100 actually 3823 02:38:38,000 --> 02:38:39,319 less than or equal to because it said 3824 02:38:39,319 --> 02:38:43,000 inclusive right 3825 02:38:43,520 --> 02:38:46,640 i++ okay um we need to think about the 3826 02:38:46,640 --> 02:38:49,279 order in which kind of these things can 3827 02:38:49,279 --> 02:38:51,000 happen happen so we're checking for 3828 02:38:51,000 --> 02:38:52,640 multiples of three multiples of five and 3829 02:38:52,640 --> 02:38:54,479 multiples of three and five so we 3830 02:38:54,479 --> 02:38:56,000 actually should check for multiples of 3831 02:38:56,000 --> 02:38:58,880 three and five first because something 3832 02:38:58,880 --> 02:39:01,760 could be that and one of the other two 3833 02:39:01,760 --> 02:39:02,920 conditions right it could be a multiple 3834 02:39:02,920 --> 02:39:05,760 of three and five and just a multiple of 3835 02:39:05,760 --> 02:39:07,840 three that makes sense maybe it'll make 3836 02:39:07,840 --> 02:39:13,680 sense when I type it out so if I 3837 02:39:14,080 --> 02:39:16,680 mod 3 3838 02:39:16,680 --> 02:39:20,880 Z and I mod 3839 02:39:20,880 --> 02:39:23,120 mod 3840 02:39:23,120 --> 02:39:26,960 three zero oops not three and three 3841 02:39:26,960 --> 02:39:30,800 three and five then we'll 3842 02:39:30,800 --> 02:39:33,359 print bizbuzz 3843 02:39:33,359 --> 02:39:35,960 right else 3844 02:39:35,960 --> 02:39:40,840 if I mod 3 3845 02:39:40,840 --> 02:39:43,800 0 then we'll just 3846 02:39:43,800 --> 02:39:46,800 print 3847 02:39:46,840 --> 02:39:52,160 is else if I imod five is zero we'll 3848 02:39:52,160 --> 02:39:53,680 just print 3849 02:39:53,680 --> 02:39:55,600 Buzz 3850 02:39:55,600 --> 02:39:59,000 otherwise we'll 3851 02:39:59,760 --> 02:40:01,520 print 3852 02:40:01,520 --> 02:40:03,760 I 3853 02:40:03,760 --> 02:40:06,160 right if they're both multiples Fizz 3854 02:40:06,160 --> 02:40:08,800 buzz if it's just three Fizz if it's 3855 02:40:08,800 --> 02:40:12,279 just five Buzz okay let's try 3856 02:40:12,279 --> 02:40:15,279 that oh cannot forget to import the 3857 02:40:15,279 --> 02:40:18,920 formatting package 3858 02:40:22,240 --> 02:40:24,479 okay let's 3859 02:40:24,479 --> 02:40:29,200 see fizzbuzz one two Fizz four Buzz five 3860 02:40:29,200 --> 02:40:34,680 Fizz seven eight fiz Buzz one oh ha one 3861 02:40:34,680 --> 02:40:36,080 through 100 that would have been close I 3862 02:40:36,080 --> 02:40:37,960 almost didn't follow instructions I was 3863 02:40:37,960 --> 02:40:39,800 like why do we have a Fizz Buzz up front 3864 02:40:39,800 --> 02:40:42,399 that doesn't uh that doesn't make sense 3865 02:40:42,399 --> 02:40:46,000 Okay cool so one two Fizz four Buzz 3866 02:40:46,000 --> 02:40:48,560 right five is a multiple of five 10 is a 3867 02:40:48,560 --> 02:40:50,399 multiple of five 3868 02:40:50,399 --> 02:40:52,920 15 is a multiple of 5 and three so this 3869 02:40:52,920 --> 02:40:55,680 is looking correct to me let me go ahead 3870 02:40:55,680 --> 02:40:57,600 and submit that so in the last 3871 02:40:57,600 --> 02:41:00,000 assignment we kind of uh did a if else 3872 02:41:00,000 --> 02:41:01,800 chain within our for Loop but there's 3873 02:41:01,800 --> 02:41:04,000 another way that we can write guard 3874 02:41:04,000 --> 02:41:06,640 Clauses within Loops um so that we don't 3875 02:41:06,640 --> 02:41:08,720 have to necessarily do that if else 3876 02:41:08,720 --> 02:41:11,279 chaining um if we don't want to uh the 3877 02:41:11,279 --> 02:41:13,120 continue keyword stops the current 3878 02:41:13,120 --> 02:41:14,600 eration of Loop and continues to the 3879 02:41:14,600 --> 02:41:16,399 next iteration so continue is a powerful 3880 02:41:16,399 --> 02:41:17,840 way to use guard classes right so we 3881 02:41:17,840 --> 02:41:20,520 write our for Loop and and then if some 3882 02:41:20,520 --> 02:41:23,040 condition happens um we can kind of bail 3883 02:41:23,040 --> 02:41:25,240 out of the body of the for Loop early 3884 02:41:25,240 --> 02:41:27,319 and just continue on to the next 3885 02:41:27,319 --> 02:41:30,000 iteration the break keyword is similar 3886 02:41:30,000 --> 02:41:32,319 in that it stops the current iteration 3887 02:41:32,319 --> 02:41:34,359 but instead of continuing on to the next 3888 02:41:34,359 --> 02:41:37,000 iteration it just ends the loop entirely 3889 02:41:37,000 --> 02:41:38,960 moving on to the assignment it says as 3890 02:41:38,960 --> 02:41:40,399 an Easter egg we decided to reward our 3891 02:41:40,399 --> 02:41:42,880 users with a free text message if they 3892 02:41:42,880 --> 02:41:45,240 send a prime number of text messages 3893 02:41:45,240 --> 02:41:47,880 this year because textio is is run by a 3894 02:41:47,880 --> 02:41:50,479 bunch of nerds complete the pr the print 3895 02:41:50,479 --> 02:41:52,080 primes function it should print all of 3896 02:41:52,080 --> 02:41:54,240 the prime numbers up to and including 3897 02:41:54,240 --> 02:41:57,399 Max Max it Should Skip any numbers that 3898 02:41:57,399 --> 02:41:59,680 are not prime okay so here's the pseudo 3899 02:41:59,680 --> 02:42:02,279 code print Prime Max so let's convert 3900 02:42:02,279 --> 02:42:07,319 this pseudo code into real go code so um 3901 02:42:07,319 --> 02:42:09,800 for n in range 2 to Max plus one so 3902 02:42:09,800 --> 02:42:13,359 we're going to do 4 n colonal 3903 02:42:13,359 --> 02:42:21,160 2 N is less than Max + 1 3904 02:42:24,040 --> 02:42:29,680 n++ okay if n is two if n is 3905 02:42:29,960 --> 02:42:33,800 two n is prime print it fmt do print 3906 02:42:33,800 --> 02:42:35,520 line 3907 02:42:35,520 --> 02:42:40,840 n and we need to continue right continue 3908 02:42:40,840 --> 02:42:42,640 to the next iteration basically saying 3909 02:42:42,640 --> 02:42:45,040 okay this n is prime we'll print it and 3910 02:42:45,040 --> 02:42:48,240 then we can move on all right if n is 3911 02:42:48,240 --> 02:42:50,640 even so so 3912 02:42:50,640 --> 02:42:55,439 if n mod 2 is zero right that's an easy 3913 02:42:55,439 --> 02:42:58,040 way to check if something is even um and 3914 02:42:58,040 --> 02:43:01,359 not make your way onto our programmer 3915 02:43:01,359 --> 02:43:04,960 humor if n mod 2 is 3916 02:43:04,960 --> 02:43:07,800 zero n is not prime skip to the next n 3917 02:43:07,800 --> 02:43:10,760 so uh we do not print and we just 3918 02:43:10,760 --> 02:43:12,720 skip 3919 02:43:12,720 --> 02:43:15,760 okay next we do a nested for Loop here 3920 02:43:15,760 --> 02:43:20,040 for I in range so for I CL 3921 02:43:20,040 --> 02:43:24,640 equal 3 to the S < TK of n + 1 okay this 3922 02:43:24,640 --> 02:43:27,080 is actually interesting I could use the 3923 02:43:27,080 --> 02:43:29,600 math. square root function here that 3924 02:43:29,600 --> 02:43:31,279 would be a valid way but if I want to 3925 02:43:31,279 --> 02:43:34,560 stay in integer land which I think I do 3926 02:43:34,560 --> 02:43:35,880 I can 3927 02:43:35,880 --> 02:43:37,680 do 3928 02:43:37,680 --> 02:43:45,439 um I can instead Square I so I * I I * I 3929 02:43:45,439 --> 02:43:47,720 and see if it's less than 3930 02:43:47,720 --> 02:43:50,200 n Plus 3931 02:43:50,200 --> 02:43:52,880 right does that make sense so instead of 3932 02:43:52,880 --> 02:43:55,600 doing I is less than the square root of 3933 02:43:55,600 --> 02:44:00,840 N I can do I SAR is less than 3934 02:44:00,840 --> 02:44:02,840 n 3935 02:44:02,840 --> 02:44:06,920 right that that makes sense to me cool 3936 02:44:06,920 --> 02:44:08,279 um because basically we're just saying 3937 02:44:08,279 --> 02:44:10,080 we only need to check up to the square 3938 02:44:10,080 --> 02:44:12,399 root of n we know that if we go higher 3939 02:44:12,399 --> 02:44:15,479 than that um but like we don't care 3940 02:44:15,479 --> 02:44:16,840 about numbers higher than the square 3941 02:44:16,840 --> 02:44:20,040 root um cool 3942 02:44:20,040 --> 02:44:22,880 next one is 3943 02:44:26,160 --> 02:44:29,439 i++ if I could be multiplied into n so 3944 02:44:29,439 --> 02:44:33,880 if n mod I 3945 02:44:33,880 --> 02:44:38,160 oops if if I goes into n evenly so if 3946 02:44:38,160 --> 02:44:42,240 that results in a zero n is not prime 3947 02:44:42,240 --> 02:44:44,040 skip to the next 3948 02:44:44,040 --> 02:44:48,240 n okay so I can't continue here because 3949 02:44:48,240 --> 02:44:49,600 if I continue here here I'll just skip 3950 02:44:49,600 --> 02:44:51,680 to the next I and I want to skip to the 3951 02:44:51,680 --> 02:44:56,120 next n so I think what I do here is I do 3952 02:44:56,120 --> 02:44:59,680 something like is 3953 02:44:59,680 --> 02:45:02,120 prime 3954 02:45:02,120 --> 02:45:05,600 true here I set is prime is 3955 02:45:05,600 --> 02:45:09,040 false and break and then at the end of 3956 02:45:09,040 --> 02:45:14,040 the for loop I can say if not is 3957 02:45:14,560 --> 02:45:16,600 prime 3958 02:45:16,600 --> 02:45:20,600 continue okay 3959 02:45:21,279 --> 02:45:24,680 okay uh if n is not prime skip to next n 3960 02:45:24,680 --> 02:45:27,600 yeah so we'll break out of this 3961 02:45:27,600 --> 02:45:30,880 Loop right we'll break out of this 3962 02:45:30,880 --> 02:45:33,800 Loop and then we'll 3963 02:45:33,800 --> 02:45:35,640 continue 3964 02:45:35,640 --> 02:45:37,800 cool now I just want to be clear there 3965 02:45:37,800 --> 02:45:39,960 are other ways to write this function 3966 02:45:39,960 --> 02:45:42,640 I'm kind of uh on purpose using lots of 3967 02:45:42,640 --> 02:45:44,800 continues and breaks uh so that we can 3968 02:45:44,800 --> 02:45:48,040 get some practice with it cool um n is 3969 02:45:48,040 --> 02:45:49,479 prime printed so if we get all the way 3970 02:45:49,479 --> 02:45:51,399 to here without any of these kind of 3971 02:45:51,399 --> 02:45:53,479 guard Clauses being triggered then n is 3972 02:45:53,479 --> 02:45:56,200 just Prime so fmt print 3973 02:45:56,200 --> 02:45:58,000 line 3974 02:45:58,000 --> 02:46:01,720 n let's run that and just sanity check 3975 02:46:01,720 --> 02:46:07,319 um our code primes up to 10 2 3 5 3976 02:46:07,319 --> 02:46:11,120 7 yep right that's two is a prime number 3977 02:46:11,120 --> 02:46:13,200 it's kind of like the only even prime 3978 02:46:13,200 --> 02:46:17,960 number and nine is an odd number before 3979 02:46:17,960 --> 02:46:20,120 10 but it's not prime because it's 3980 02:46:20,120 --> 02:46:22,640 evenly divided into by three right maybe 3981 02:46:22,640 --> 02:46:24,520 I should have even explained what prime 3982 02:46:24,520 --> 02:46:26,000 numbers are in the first place in case 3983 02:46:26,000 --> 02:46:28,760 you're not familiar um there is uh there 3984 02:46:28,760 --> 02:46:30,640 is a link here if you want to go read 3985 02:46:30,640 --> 02:46:32,520 more about them but basically a prime 3986 02:46:32,520 --> 02:46:36,240 number is any number where the numbers 3987 02:46:36,240 --> 02:46:39,359 that multiply evenly into it are 3988 02:46:39,359 --> 02:46:42,040 anything except one in itself so if it 3989 02:46:42,040 --> 02:46:45,160 has any multiples or if it has anything 3990 02:46:45,160 --> 02:46:48,520 that multiplies into it that isn't just 3991 02:46:48,520 --> 02:46:52,439 one and itself it's Prime right so seven 3992 02:46:52,439 --> 02:46:55,240 you can't you can't multiply two into 3993 02:46:55,240 --> 02:46:57,160 seven you can't multiply three into 3994 02:46:57,160 --> 02:46:59,439 seven you can't multiply four into seven 3995 02:46:59,439 --> 02:47:01,120 right um so it's 3996 02:47:01,120 --> 02:47:03,960 Prime um let's just uh look at a couple 3997 02:47:03,960 --> 02:47:06,600 more of the examples so up to 20 we got 3998 02:47:06,600 --> 02:47:09,960 2 3 5 7 11 13 17 19 right again we're 3999 02:47:09,960 --> 02:47:12,200 skipping 15 because it has the multiples 4000 02:47:12,200 --> 02:47:13,680 three and 4001 02:47:13,680 --> 02:47:17,600 five primes up to 30 um again skipping 4002 02:47:17,600 --> 02:47:21,920 25 um and also skipping 27 because 9 4003 02:47:21,920 --> 02:47:25,399 divides evenly into 27 as as just three 4004 02:47:25,399 --> 02:47:28,160 cool so hopefully that makes a bit of 4005 02:47:28,160 --> 02:47:31,080 sense and then just kind of as a as an 4006 02:47:31,080 --> 02:47:33,279 explanation of of why this pseudo code 4007 02:47:33,279 --> 02:47:34,760 Works we're skipping even numbers 4008 02:47:34,760 --> 02:47:37,399 because they can't be prime right if it 4009 02:47:37,399 --> 02:47:38,880 if two divides into something it's not 4010 02:47:38,880 --> 02:47:40,640 prime um we only check up to the square 4011 02:47:40,640 --> 02:47:42,399 root because anything higher than the 4012 02:47:42,399 --> 02:47:44,800 square root has no chance of multiplying 4013 02:47:44,800 --> 02:47:48,840 evenly into n right so like for example 4014 02:47:48,840 --> 02:47:50,560 take the number 16 its square root is 4015 02:47:50,560 --> 02:47:54,840 four nothing over four could possibly 4016 02:47:54,840 --> 02:47:57,399 evenly divide into 4017 02:47:57,399 --> 02:48:00,479 16 that the square root couldn't right 4018 02:48:00,479 --> 02:48:02,520 so like for example 8 divides evenly 4019 02:48:02,520 --> 02:48:05,160 into 16 but that's only because four and 4020 02:48:05,160 --> 02:48:06,680 two already 4021 02:48:06,680 --> 02:48:09,520 do okay uh we start checking at two 4022 02:48:09,520 --> 02:48:12,520 because one is not prime one's kind of a 4023 02:48:12,520 --> 02:48:13,720 special case 4024 02:48:13,720 --> 02:48:15,800 number okay so this is looking correct 4025 02:48:15,800 --> 02:48:18,000 to me I'm going to go ahead and submit 4026 02:48:18,000 --> 02:48:20,319 it 4027 02:48:20,319 --> 02:48:22,720 let's talk a little bit about how arrays 4028 02:48:22,720 --> 02:48:24,399 work under the hood so if you're 4029 02:48:24,399 --> 02:48:26,760 familiar with the idea of arrays from 4030 02:48:26,760 --> 02:48:29,680 JavaScript or lists from python arrays 4031 02:48:29,680 --> 02:48:33,240 and go are similar you can think of an 4032 02:48:33,240 --> 02:48:36,800 array is just an ordered list of items 4033 02:48:36,800 --> 02:48:39,160 so we usually denote arrays with square 4034 02:48:39,160 --> 02:48:42,000 brackets and an array of say three 4035 02:48:42,000 --> 02:48:47,680 integers might be something like 2 3 1 4036 02:48:47,680 --> 02:48:49,439 right so we've got three integers 4037 02:48:49,439 --> 02:48:52,479 stored in our array the first thing is 4038 02:48:52,479 --> 02:48:55,880 the integer 2 it's stored at index zero 4039 02:48:55,880 --> 02:48:57,640 the next one is a three it's stored at 4040 02:48:57,640 --> 02:49:00,560 index one and finally we have a one 4041 02:49:00,560 --> 02:49:04,080 stored at index 2 now here's the big 4042 02:49:04,080 --> 02:49:06,000 difference between arrays in go and 4043 02:49:06,000 --> 02:49:08,880 arrays in JavaScript or lists in Python 4044 02:49:08,880 --> 02:49:12,520 in go arrays have a fixed size so the 4045 02:49:12,520 --> 02:49:15,560 type of this array would 4046 02:49:15,560 --> 02:49:19,560 be three 4047 02:49:20,920 --> 02:49:24,200 int so inside of the square brackets we 4048 02:49:24,200 --> 02:49:26,319 kind of indicate the size of the array 4049 02:49:26,319 --> 02:49:29,080 and then after we indicate the type of 4050 02:49:29,080 --> 02:49:32,520 thing in the array so this array's type 4051 02:49:32,520 --> 02:49:35,680 is an array of three integers in 4052 02:49:35,680 --> 02:49:38,200 languages like JavaScript or again like 4053 02:49:38,200 --> 02:49:41,399 lists in Python arrays are kind of 4054 02:49:41,399 --> 02:49:43,520 dynamically resize they don't have a 4055 02:49:43,520 --> 02:49:45,399 fixed size you can add things onto the 4056 02:49:45,399 --> 02:49:47,399 end you can push stuff onto the 4057 02:49:47,399 --> 02:49:51,040 beginning but in go arrays are always 4058 02:49:51,040 --> 02:49:53,319 fixed so to show you what this looks 4059 02:49:53,319 --> 02:49:55,520 like in code um basically we can create 4060 02:49:55,520 --> 02:50:00,040 a new array of 10 integers like this it 4061 02:50:00,040 --> 02:50:02,760 will initialize all of the indices in 4062 02:50:02,760 --> 02:50:04,279 the array to the zero value so this 4063 02:50:04,279 --> 02:50:08,120 would be an array of 10 zeros basically 4064 02:50:08,120 --> 02:50:10,600 um if we know what we want to store at 4065 02:50:10,600 --> 02:50:13,040 each index in the array then we can use 4066 02:50:13,040 --> 02:50:14,439 an initialize literal here so we're 4067 02:50:14,439 --> 02:50:17,319 saying we have an array of six integers 4068 02:50:17,319 --> 02:50:19,160 and in the first index I wanted to two 4069 02:50:19,160 --> 02:50:21,200 and then a three and then a five and so 4070 02:50:21,200 --> 02:50:23,479 on so let's jump into an assignment and 4071 02:50:23,479 --> 02:50:25,880 see how this works the assignment says 4072 02:50:25,880 --> 02:50:27,439 when a message is not responded to we 4073 02:50:27,439 --> 02:50:29,080 allow our clients to have up to two 4074 02:50:29,080 --> 02:50:30,560 additional messages that are sent as 4075 02:50:30,560 --> 02:50:33,399 nudging reminders get message with 4076 02:50:33,399 --> 02:50:35,600 retries returns an array of three 4077 02:50:35,600 --> 02:50:37,600 strings where index zero is the first 4078 02:50:37,600 --> 02:50:39,640 message if the first message is not 4079 02:50:39,640 --> 02:50:41,000 answered by the recipient we send the 4080 02:50:41,000 --> 02:50:43,600 second and then we'd send the third 4081 02:50:43,600 --> 02:50:45,359 update get message with reti to return 4082 02:50:45,359 --> 02:50:47,880 the three following strings in an array 4083 02:50:47,880 --> 02:50:49,479 click here to sign up PR please click 4084 02:50:49,479 --> 02:50:51,760 here we beg you to sign up Okay cool so 4085 02:50:51,760 --> 02:50:53,319 this is pretty straightforward here 4086 02:50:53,319 --> 02:50:54,720 we're just going to 4087 02:50:54,720 --> 02:50:57,399 return an array and you can see the 4088 02:50:57,399 --> 02:51:00,040 return type up here it's a string array 4089 02:51:00,040 --> 02:51:03,880 of size three so we just need to create 4090 02:51:03,880 --> 02:51:06,920 an array literal and return it and in 4091 02:51:06,920 --> 02:51:10,200 this case we want an array of strings of 4092 02:51:10,200 --> 02:51:13,239 size three so array string size three 4093 02:51:13,239 --> 02:51:16,040 and we can use these curly 4094 02:51:16,040 --> 02:51:20,120 brackets um to be kind of where we put 4095 02:51:20,120 --> 02:51:21,680 the string literal so the first string 4096 02:51:21,680 --> 02:51:23,920 is going to be click here to sign up 4097 02:51:23,920 --> 02:51:26,640 right this is the first message that's 4098 02:51:26,640 --> 02:51:30,399 sent pretty please click 4099 02:51:30,399 --> 02:51:33,800 here and we beg you we beg you to sign 4100 02:51:33,800 --> 02:51:36,319 up and then just remember that in go you 4101 02:51:36,319 --> 02:51:39,200 do have to put that last comma um if 4102 02:51:39,200 --> 02:51:40,800 you're going to use a new 4103 02:51:40,800 --> 02:51:44,200 line okay um pretty straightforward 4104 02:51:44,200 --> 02:51:47,520 right let's see how that 4105 02:51:47,520 --> 02:51:50,479 works 4106 02:51:50,479 --> 02:51:53,160 sending sending to Bob click here to 4107 02:51:53,160 --> 02:51:55,319 sign up they responded sending to Alice 4108 02:51:55,319 --> 02:51:56,880 click here to sign up pry please click 4109 02:51:56,880 --> 02:52:00,080 here they responded okay this is looking 4110 02:52:00,080 --> 02:52:03,080 this is looking good to 4111 02:52:03,720 --> 02:52:08,399 me going to kind of get a peek at the 4112 02:52:09,160 --> 02:52:11,359 uh at the test 4113 02:52:11,359 --> 02:52:14,359 Suite cool let's submit it and see how 4114 02:52:14,359 --> 02:52:17,120 we did so we've talked about how arrays 4115 02:52:17,120 --> 02:52:18,920 are fixed in size and you might be 4116 02:52:18,920 --> 02:52:21,120 wondering well that's not very useful 4117 02:52:21,120 --> 02:52:23,239 why would I care about an ordered list 4118 02:52:23,239 --> 02:52:25,720 of things if I can't even add to or 4119 02:52:25,720 --> 02:52:28,160 remove from the list well that's where 4120 02:52:28,160 --> 02:52:31,760 slices come into play so let's draw out 4121 02:52:31,760 --> 02:52:33,479 a simple 4122 02:52:33,479 --> 02:52:36,319 array I'll do it in yellow let's just 4123 02:52:36,319 --> 02:52:37,800 say it's storing some numbers we might 4124 02:52:37,800 --> 02:52:43,040 have some numbers like six 3 2 4125 02:52:43,040 --> 02:52:47,200 6 five and I'll draw the indices let's 4126 02:52:47,200 --> 02:52:49,760 do that in pink so the index of the 4127 02:52:49,760 --> 02:52:54,399 first item is zero and then 1 2 3 4 4128 02:52:54,399 --> 02:52:57,080 right and the size of the array is five 4129 02:52:57,080 --> 02:52:59,479 which in go we would write like like 4130 02:52:59,479 --> 02:53:03,120 this we would say we have an array of 4131 02:53:03,120 --> 02:53:06,720 five items and they are integers Okay 4132 02:53:06,720 --> 02:53:08,760 cool so we understand what an array is 4133 02:53:08,760 --> 02:53:11,880 but what's a slice well slices in go are 4134 02:53:11,880 --> 02:53:15,279 written with this syntax open close 4135 02:53:15,279 --> 02:53:19,080 bracket int and you'll notice that the 4136 02:53:19,080 --> 02:53:23,840 size is missing okay so a slice is a 4137 02:53:23,840 --> 02:53:27,319 dynamically sized flexible view into an 4138 02:53:27,319 --> 02:53:29,640 array so slices are built on top of 4139 02:53:29,640 --> 02:53:32,520 arrays so that means for example that I 4140 02:53:32,520 --> 02:53:36,399 could create a slice that just looks at 4141 02:53:36,399 --> 02:53:38,880 this kind of middle 4142 02:53:38,880 --> 02:53:41,920 portion of this array if I were to write 4143 02:53:41,920 --> 02:53:43,720 this in code I would basically say if 4144 02:53:43,720 --> 02:53:47,000 this array is named a so a is this 4145 02:53:47,000 --> 02:53:49,080 yellow array here if if I want to create 4146 02:53:49,080 --> 02:53:52,040 a slice on top of that array then I 4147 02:53:52,040 --> 02:53:54,080 could write 4148 02:53:54,080 --> 02:53:57,560 B colon equals 4149 02:53:57,560 --> 02:54:01,960 a from we're using square brackets here 4150 02:54:01,960 --> 02:54:03,680 index 4151 02:54:03,680 --> 02:54:08,399 one up to but not including index 4 okay 4152 02:54:08,399 --> 02:54:09,680 so the first the first number is 4153 02:54:09,680 --> 02:54:12,479 inclusive the second number is exclusive 4154 02:54:12,479 --> 02:54:16,399 and now B is this slice of kind of just 4155 02:54:16,399 --> 02:54:18,920 that middle view of the array and here's 4156 02:54:18,920 --> 02:54:21,399 the important thing to understand in go 4157 02:54:21,399 --> 02:54:24,080 we actually almost never deal with 4158 02:54:24,080 --> 02:54:28,000 arrays directly 99 times out of 100 4159 02:54:28,000 --> 02:54:30,600 you'll just be working with slices 4160 02:54:30,600 --> 02:54:32,359 because slices provide a much better 4161 02:54:32,359 --> 02:54:35,080 developer experience they're built on 4162 02:54:35,080 --> 02:54:37,040 top of arrays for kind of memory 4163 02:54:37,040 --> 02:54:38,439 management reasons which we'll talk 4164 02:54:38,439 --> 02:54:40,520 about in just a second but you really 4165 02:54:40,520 --> 02:54:43,160 want to be working um for the most part 4166 02:54:43,160 --> 02:54:44,800 with slices because you don't have to 4167 02:54:44,800 --> 02:54:47,960 worry about that fixed size problem so 4168 02:54:47,960 --> 02:54:51,520 just review slices sort of in code um we 4169 02:54:51,520 --> 02:54:54,880 can create an array literal like this 4170 02:54:54,880 --> 02:54:56,800 right this is an array because we have 4171 02:54:56,800 --> 02:54:59,560 we have the uh size of the array there 4172 02:54:59,560 --> 02:55:02,040 six integers and then we can create a 4173 02:55:02,040 --> 02:55:06,120 slice on top of the array like this cool 4174 02:55:06,120 --> 02:55:07,640 um let's jump into the assignment so you 4175 02:55:07,640 --> 02:55:09,880 can kind of get a feel for how this all 4176 02:55:09,880 --> 02:55:12,479 works okay the assignment says retries 4177 02:55:12,479 --> 02:55:14,399 are a premium feature now textos free 4178 02:55:14,399 --> 02:55:16,640 users only get one retry message while 4179 02:55:16,640 --> 02:55:18,840 Pro members get an unlimited amount 4180 02:55:18,840 --> 02:55:20,359 complete the get message with retries 4181 02:55:20,359 --> 02:55:22,600 for plan function it takes a plan 4182 02:55:22,600 --> 02:55:24,359 variable as input that's a string 4183 02:55:24,359 --> 02:55:26,720 matches up to one of these um if the 4184 02:55:26,720 --> 02:55:28,800 plan is a Pro Plan return all of the 4185 02:55:28,800 --> 02:55:31,040 strings from get message with retries 4186 02:55:31,040 --> 02:55:32,920 Okay cool so get message with retries it 4187 02:55:32,920 --> 02:55:34,200 looks like 4188 02:55:34,200 --> 02:55:36,840 returns an array of three 4189 02:55:36,840 --> 02:55:39,120 strings okay let's just jump right into 4190 02:55:39,120 --> 02:55:43,239 it if plan is plan 4191 02:55:43,239 --> 02:55:47,120 Pro then we'll return all messages right 4192 02:55:47,120 --> 02:55:50,520 return all the strings yep and a nil 4193 02:55:50,520 --> 02:55:53,080 error otherwise if the 4194 02:55:53,080 --> 02:55:56,560 plan is plan 4195 02:55:56,560 --> 02:55:59,479 free return the first two strings right 4196 02:55:59,479 --> 02:56:01,600 the original string and kind of the one 4197 02:56:01,600 --> 02:56:04,600 the first retry message so return all 4198 02:56:04,600 --> 02:56:07,080 messages and we're going to slice it 4199 02:56:07,080 --> 02:56:09,279 from index zero up to but not including 4200 02:56:09,279 --> 02:56:11,279 index two so that'll be indexes zero and 4201 02:56:11,279 --> 02:56:14,560 one right two two strings and then we'll 4202 02:56:14,560 --> 02:56:16,120 also return 4203 02:56:16,120 --> 02:56:19,120 nil and finally if it's neither of those 4204 02:56:19,120 --> 02:56:22,000 return an error that says unsupported 4205 02:56:22,000 --> 02:56:28,279 plan so return nil errors. new 4206 02:56:28,279 --> 02:56:31,560 unsupported plan and nil um is just kind 4207 02:56:31,560 --> 02:56:34,080 of the zero value of 4208 02:56:34,080 --> 02:56:36,600 slice cool um this is looking good we 4209 02:56:36,600 --> 02:56:39,600 need to make sure we import the errors 4210 02:56:39,600 --> 02:56:41,640 package let's go ahead and run this and 4211 02:56:41,640 --> 02:56:42,920 see what 4212 02:56:42,920 --> 02:56:46,120 happens o we got an error cannot use all 4213 02:56:46,120 --> 02:56:49,359 messages variable of type 4214 02:56:49,359 --> 02:56:52,520 array size three string as slice of 4215 02:56:52,520 --> 02:56:56,600 string Okay cool so we have an 4216 02:56:56,600 --> 02:56:59,479 array all messages is an array not a 4217 02:56:59,479 --> 02:57:02,600 slice right so we actually need to slice 4218 02:57:02,600 --> 02:57:06,920 this to change its type but we want all 4219 02:57:06,920 --> 02:57:08,680 of the values inside of the array so 4220 02:57:08,680 --> 02:57:10,760 we're just going to use this colon 4221 02:57:10,760 --> 02:57:13,960 syntax to get access to everything in 4222 02:57:13,960 --> 02:57:15,800 the underlying array let's run that 4223 02:57:15,800 --> 02:57:18,800 again 4224 02:57:20,560 --> 02:57:21,800 cool sending to 4225 02:57:21,800 --> 02:57:24,319 osar click here to sign up pretty please 4226 02:57:24,319 --> 02:57:26,439 click here so that's two two messages 4227 02:57:26,439 --> 02:57:27,399 with no 4228 02:57:27,399 --> 02:57:29,800 response um and I'm guessing because yep 4229 02:57:29,800 --> 02:57:32,880 ozer is on a free plan Jess Jeff is on a 4230 02:57:32,880 --> 02:57:35,520 Pro Plan so he gets all three messages 4231 02:57:35,520 --> 02:57:37,479 this is looking correct to me these next 4232 02:57:37,479 --> 02:57:39,399 few questions will reference kind of 4233 02:57:39,399 --> 02:57:42,120 excerpts from the effective gobook which 4234 02:57:42,120 --> 02:57:44,040 is definitely a book I recommend reading 4235 02:57:44,040 --> 02:57:46,239 although it is a bit out of date it was 4236 02:57:46,239 --> 02:57:49,200 written a while ago um and the authors 4237 02:57:49,200 --> 02:57:50,840 have basically made the decision not to 4238 02:57:50,840 --> 02:57:53,200 update um the book over time kind of 4239 02:57:53,200 --> 02:57:55,080 keeping it as a snapshot so it has a lot 4240 02:57:55,080 --> 02:57:57,239 of great stuff in there and go has very 4241 02:57:57,239 --> 02:57:58,600 strong backwards compatibility so it's 4242 02:57:58,600 --> 02:58:00,160 still a great read um just kind of be 4243 02:58:00,160 --> 02:58:03,160 aware that it hasn't been updated um in 4244 02:58:03,160 --> 02:58:07,239 a while cool um that said everything we 4245 02:58:07,239 --> 02:58:09,680 explained here I'll obviously provide uh 4246 02:58:09,680 --> 02:58:13,960 context um for so the thing that's 4247 02:58:13,960 --> 02:58:16,080 important to understand in this section 4248 02:58:16,080 --> 02:58:20,279 is that slices are references to kind of 4249 02:58:20,279 --> 02:58:22,680 what goes on underneath the hood with 4250 02:58:22,680 --> 02:58:26,680 arrays so what that really means to you 4251 02:58:26,680 --> 02:58:29,600 as a developer is when you use slices 4252 02:58:29,600 --> 02:58:31,399 and more specifically when you pass them 4253 02:58:31,399 --> 02:58:33,680 around say into a function you're 4254 02:58:33,680 --> 02:58:36,560 actually passing a reference which means 4255 02:58:36,560 --> 02:58:40,279 if you change the values in that slice 4256 02:58:40,279 --> 02:58:43,560 within a function the caller the person 4257 02:58:43,560 --> 02:58:44,960 who called your function or I should say 4258 02:58:44,960 --> 02:58:46,239 the bit of code that called your 4259 02:58:46,239 --> 02:58:48,399 function will actually have access to 4260 02:58:48,399 --> 02:58:51,000 those changes it will see those changes 4261 02:58:51,000 --> 02:58:53,399 even if you don't explicitly return the 4262 02:58:53,399 --> 02:58:56,319 slice again now this is different um 4263 02:58:56,319 --> 02:58:58,399 from sort of normal primitive values 4264 02:58:58,399 --> 02:59:00,200 which are passed by value you might 4265 02:59:00,200 --> 02:59:02,479 remember us talking about pass by value 4266 02:59:02,479 --> 02:59:05,160 earlier in the course typically if you 4267 02:59:05,160 --> 02:59:07,439 pass in say a string or an integer into 4268 02:59:07,439 --> 02:59:09,080 a function and then within that function 4269 02:59:09,080 --> 02:59:11,399 you change it the caller won't see those 4270 02:59:11,399 --> 02:59:13,800 changes you have your own copy of that 4271 02:59:13,800 --> 02:59:16,720 data that's that does not hold true with 4272 02:59:16,720 --> 02:59:18,920 slices so just understand that when you 4273 02:59:18,920 --> 02:59:21,080 pass a slice into a function it might 4274 02:59:21,080 --> 02:59:21,840 get 4275 02:59:21,840 --> 02:59:25,160 modified okay cool um so which 4276 02:59:25,160 --> 02:59:27,800 references the other is the question do 4277 02:59:27,800 --> 02:59:29,880 arrays reference slices or do slices 4278 02:59:29,880 --> 02:59:31,840 reference arrays and the answer is that 4279 02:59:31,840 --> 02:59:34,760 slices reference arrays the next 4280 02:59:34,760 --> 02:59:37,560 question is can multiple slices point to 4281 02:59:37,560 --> 02:59:39,680 the same array is that true or false 4282 02:59:39,680 --> 02:59:41,760 multiple slices point to the same array 4283 02:59:41,760 --> 02:59:45,439 um that is true remember slices are just 4284 02:59:45,439 --> 02:59:48,120 kind of a view into an array so it makes 4285 02:59:48,120 --> 02:59:49,800 sense that you can have multiple views 4286 02:59:49,800 --> 02:59:52,439 into the same underlying array so 4287 02:59:52,439 --> 02:59:54,880 multiple slices can point to the same 4288 02:59:54,880 --> 02:59:57,479 array now here's that question um that 4289 02:59:57,479 --> 02:59:59,800 we talked about earlier a function that 4290 02:59:59,800 --> 03:00:03,359 only has access to a slice can modify 4291 03:00:03,359 --> 03:00:06,359 the underlying array the answer to this 4292 03:00:06,359 --> 03:00:09,279 is that is true even if the function 4293 03:00:09,279 --> 03:00:12,279 doesn't return that slice it can modify 4294 03:00:12,279 --> 03:00:15,120 the values in the underlying array let's 4295 03:00:15,120 --> 03:00:17,160 talk about how slices work um kind of 4296 03:00:17,160 --> 03:00:18,920 specifically how work in relation to 4297 03:00:18,920 --> 03:00:21,080 your computer's Hardware or your 4298 03:00:21,080 --> 03:00:24,880 computer's Ram now Ram just stands for 4299 03:00:24,880 --> 03:00:27,160 Random Access Memory it's where 4300 03:00:27,160 --> 03:00:29,040 variables are stored the best way to 4301 03:00:29,040 --> 03:00:32,680 think about Ram is just a mapping of 4302 03:00:32,680 --> 03:00:35,160 addresses so 4303 03:00:35,160 --> 03:00:37,640 address to 4304 03:00:37,640 --> 03:00:40,640 data right it gives us a place to store 4305 03:00:40,640 --> 03:00:44,479 stuff so for example at address 4306 03:00:44,479 --> 03:00:47,479 Z we might have some data that 4307 03:00:47,479 --> 03:00:50,279 represents I don't know the number four 4308 03:00:50,279 --> 03:00:54,000 right and then at address one we might 4309 03:00:54,000 --> 03:00:55,880 have some data representing the number 4310 03:00:55,880 --> 03:00:57,960 five I don't know I'm just making stuff 4311 03:00:57,960 --> 03:01:00,200 up but you get the idea we have 4312 03:01:00,200 --> 03:01:03,399 addresses and we have data associated 4313 03:01:03,399 --> 03:01:06,920 with that address slices and the arrays 4314 03:01:06,920 --> 03:01:09,200 that they are built on top of are stored 4315 03:01:09,200 --> 03:01:11,960 in contiguous memory basically what that 4316 03:01:11,960 --> 03:01:16,600 means is a slice or an array is an 4317 03:01:16,600 --> 03:01:18,640 address in memory where where the slice 4318 03:01:18,640 --> 03:01:21,279 or array starts so for example at 4319 03:01:21,279 --> 03:01:23,680 address zero we might say this is the 4320 03:01:23,680 --> 03:01:26,080 start of a 4321 03:01:26,080 --> 03:01:29,359 slice and the slice actually continues 4322 03:01:29,359 --> 03:01:32,800 for the next you know several uh kind of 4323 03:01:32,800 --> 03:01:34,680 bytes of data let's say that it's a 4324 03:01:34,680 --> 03:01:36,800 slice of length three so it actually 4325 03:01:36,800 --> 03:01:39,760 would reach across all three of these 4326 03:01:39,760 --> 03:01:42,080 addresses so if you have an array or a 4327 03:01:42,080 --> 03:01:45,880 slice um and its address is zero and its 4328 03:01:45,880 --> 03:01:49,000 length is three then you know kind of 4329 03:01:49,000 --> 03:01:53,040 how many uh stores of data in memory um 4330 03:01:53,040 --> 03:01:56,840 your slice or array will use now this is 4331 03:01:56,840 --> 03:01:59,319 primarily important for performance 4332 03:01:59,319 --> 03:02:01,960 because all of the data is stored next 4333 03:02:01,960 --> 03:02:04,080 to each other in memory it's going to be 4334 03:02:04,080 --> 03:02:06,239 faster to kind of iterate over all of 4335 03:02:06,239 --> 03:02:08,960 the values in our slice if we stored 4336 03:02:08,960 --> 03:02:11,359 each index in kind of random places in 4337 03:02:11,359 --> 03:02:13,120 memory it would take a lot longer to go 4338 03:02:13,120 --> 03:02:15,120 collect all of that data just you know 4339 03:02:15,120 --> 03:02:17,359 from a hardware perspective however 4340 03:02:17,359 --> 03:02:20,560 there is a downside to having to store 4341 03:02:20,560 --> 03:02:23,359 all of our memory um kind of next to 4342 03:02:23,359 --> 03:02:26,359 each other let's pretend that we have 4343 03:02:26,359 --> 03:02:28,560 this slice or this array that starts at 4344 03:02:28,560 --> 03:02:30,359 address zero and has a length of three 4345 03:02:30,359 --> 03:02:32,319 so it's using kind of these three 4346 03:02:32,319 --> 03:02:34,600 addresses in memory or these three bytes 4347 03:02:34,600 --> 03:02:37,920 of memory and let's say here at address 4348 03:02:37,920 --> 03:02:41,000 3 we're storing a different value maybe 4349 03:02:41,000 --> 03:02:42,840 we're just storing I don't know the 4350 03:02:42,840 --> 03:02:46,479 number six um but this is a different 4351 03:02:46,479 --> 03:02:48,439 variable 4352 03:02:48,439 --> 03:02:50,920 this is some other variable the problem 4353 03:02:50,920 --> 03:02:54,160 is if we want to expand our slice say 4354 03:02:54,160 --> 03:02:56,080 add another value to it we're going to 4355 03:02:56,080 --> 03:02:58,640 run into the next thing in physical 4356 03:02:58,640 --> 03:03:00,239 memory that's a huge problem we don't 4357 03:03:00,239 --> 03:03:02,560 want to overwrite some other variable 4358 03:03:02,560 --> 03:03:05,520 just because we're growing our slice so 4359 03:03:05,520 --> 03:03:08,279 this is why arrays are fixed in size if 4360 03:03:08,279 --> 03:03:10,520 we just can't grow them then we'll never 4361 03:03:10,520 --> 03:03:13,720 have this overwriting problem so the the 4362 03:03:13,720 --> 03:03:15,479 question of course is how do slices do 4363 03:03:15,479 --> 03:03:17,800 it right well slices are built on top of 4364 03:03:17,800 --> 03:03:20,760 rays and basically what happens is I can 4365 03:03:20,760 --> 03:03:23,600 draw this out for us when we want to 4366 03:03:23,600 --> 03:03:25,040 grow a 4367 03:03:25,040 --> 03:03:28,359 slice whose underlying array has run out 4368 03:03:28,359 --> 03:03:31,840 of room right so we have our slice um 4369 03:03:31,840 --> 03:03:34,000 built on top of this length three array 4370 03:03:34,000 --> 03:03:36,279 and we want to grow it into a length of 4371 03:03:36,279 --> 03:03:38,640 four what happens under the hood and 4372 03:03:38,640 --> 03:03:40,439 this all kind of happens without you 4373 03:03:40,439 --> 03:03:41,840 seeing it as a developer you'll you'll 4374 03:03:41,840 --> 03:03:43,640 see later when we get to the syntax it's 4375 03:03:43,640 --> 03:03:45,720 actually really simple um what happens 4376 03:03:45,720 --> 03:03:47,359 is this data is copied into a new 4377 03:03:47,359 --> 03:03:49,359 location memory so we just take this 4378 03:03:49,359 --> 03:03:53,600 four we put it over here five over here 4379 03:03:53,600 --> 03:03:54,800 uh actually I'm going to use the same 4380 03:03:54,800 --> 03:03:56,680 colors that would probably be easier to 4381 03:03:56,680 --> 03:03:59,760 understand so four comes over here five 4382 03:03:59,760 --> 03:04:02,760 comes over here three comes over here 4383 03:04:02,760 --> 03:04:05,319 and then let's say that we um we know we 4384 03:04:05,319 --> 03:04:07,359 want to grow our slice significantly so 4385 03:04:07,359 --> 03:04:09,600 the new underlying 4386 03:04:09,600 --> 03:04:12,760 array let's say will have a length of 4387 03:04:12,760 --> 03:04:16,080 six now so it had three here now the new 4388 03:04:16,080 --> 03:04:19,720 array has allocated pre-allocated right 4389 03:04:19,720 --> 03:04:22,120 we've essentially reserved memory for up 4390 03:04:22,120 --> 03:04:27,640 to six spaces let me draw all of that 4391 03:04:27,640 --> 03:04:31,399 out cool and these addresses over here 4392 03:04:31,399 --> 03:04:32,640 are going to be totally different right 4393 03:04:32,640 --> 03:04:37,760 maybe it's address 15 address 16 17 18 4394 03:04:37,760 --> 03:04:40,279 19 and 4395 03:04:40,279 --> 03:04:42,520 20 cool so all the data from the old 4396 03:04:42,520 --> 03:04:44,560 array gets copied over and now we're 4397 03:04:44,560 --> 03:04:48,720 able to expand our slice 4398 03:04:48,720 --> 03:04:50,920 our slice to a length of 4399 03:04:50,920 --> 03:04:53,680 four right so here our slice was length 4400 03:04:53,680 --> 03:04:55,760 three and the underlying array was 4401 03:04:55,760 --> 03:04:58,920 length three now we've copied over the 4402 03:04:58,920 --> 03:05:01,319 data we've created a much larger 4403 03:05:01,319 --> 03:05:04,640 underlying array and now we have a slice 4404 03:05:04,640 --> 03:05:06,640 of length four maybe we wanted to append 4405 03:05:06,640 --> 03:05:08,920 say the number two to the end of the 4406 03:05:08,920 --> 03:05:11,279 slice so again as the developer you're 4407 03:05:11,279 --> 03:05:13,200 not going to have to do all of this 4408 03:05:13,200 --> 03:05:16,239 array management manually but it's 4409 03:05:16,239 --> 03:05:17,920 important to understand that this is 4410 03:05:17,920 --> 03:05:19,319 what's going on under the hood because 4411 03:05:19,319 --> 03:05:22,080 it has performance implications copying 4412 03:05:22,080 --> 03:05:24,720 data isn't super efficient if you're 4413 03:05:24,720 --> 03:05:27,319 copying data from one section in memory 4414 03:05:27,319 --> 03:05:29,520 to another um over and over and over 4415 03:05:29,520 --> 03:05:32,359 again it can slow down your programs so 4416 03:05:32,359 --> 03:05:34,000 now that we've covered all of that 4417 03:05:34,000 --> 03:05:36,040 memory stuff and how it works under the 4418 03:05:36,040 --> 03:05:39,000 hood what does that mean in code right 4419 03:05:39,000 --> 03:05:42,000 well this is how we can create a slice 4420 03:05:42,000 --> 03:05:44,359 without explicitly creating an array 4421 03:05:44,359 --> 03:05:46,200 under the hood right so this will 4422 03:05:46,200 --> 03:05:48,120 automatically create an an array under 4423 03:05:48,120 --> 03:05:50,439 the hood for us if we use this syntax so 4424 03:05:50,439 --> 03:05:51,960 this is basically saying I want a new 4425 03:05:51,960 --> 03:05:54,880 slice of integers I want its initial 4426 03:05:54,880 --> 03:05:57,439 length to be five so the length of the 4427 03:05:57,439 --> 03:05:59,760 slice right the length of the view into 4428 03:05:59,760 --> 03:06:03,720 the array will be five and the capacity 4429 03:06:03,720 --> 03:06:07,439 will be 10 so the capacity is kind of 4430 03:06:07,439 --> 03:06:09,960 the total space that we have to grow the 4431 03:06:09,960 --> 03:06:12,880 slice until we need to allocate a new 4432 03:06:12,880 --> 03:06:14,439 array under the hood so you could almost 4433 03:06:14,439 --> 03:06:16,359 think of this capacity is just the 4434 03:06:16,359 --> 03:06:18,680 length of the underlying array now I 4435 03:06:18,680 --> 03:06:20,000 told you that you don't need to think 4436 03:06:20,000 --> 03:06:21,200 about the size of the under the Ling 4437 03:06:21,200 --> 03:06:23,840 array and that is true typically you'll 4438 03:06:23,840 --> 03:06:25,760 actually use this syntax where you don't 4439 03:06:25,760 --> 03:06:30,319 even specify a capacity so if you do not 4440 03:06:30,319 --> 03:06:32,279 specify a capacity it defaults to the 4441 03:06:32,279 --> 03:06:35,000 length so the kind of length of the 4442 03:06:35,000 --> 03:06:37,600 underlying array for a slice of integers 4443 03:06:37,600 --> 03:06:40,000 with length five will just be five and 4444 03:06:40,000 --> 03:06:42,319 if you grow it past that the memory 4445 03:06:42,319 --> 03:06:44,520 copying will happen and you'll create a 4446 03:06:44,520 --> 03:06:46,560 new underlying array now you might be 4447 03:06:46,560 --> 03:06:47,800 thinking oh that's terrible for 4448 03:06:47,800 --> 03:06:51,319 performance in reality it's not that bad 4449 03:06:51,319 --> 03:06:52,880 the only reason you would start to kind 4450 03:06:52,880 --> 03:06:55,560 of fuss with specific capacities and 4451 03:06:55,560 --> 03:06:57,760 optimizing your memory copying is if 4452 03:06:57,760 --> 03:07:00,319 you're having performance problems 4453 03:07:00,319 --> 03:07:02,920 generally speaking the convenience of 4454 03:07:02,920 --> 03:07:04,640 keeping your code simple and easy to 4455 03:07:04,640 --> 03:07:07,040 understand is going to outweigh kind of 4456 03:07:07,040 --> 03:07:09,399 the performance cost that it'll have 4457 03:07:09,399 --> 03:07:11,160 it's it's a very small one generally 4458 03:07:11,160 --> 03:07:13,000 speaking and then it's also just worth 4459 03:07:13,000 --> 03:07:14,720 pointing out that we can also create 4460 03:07:14,720 --> 03:07:16,560 slice literals right so this just 4461 03:07:16,560 --> 03:07:18,760 creates a new slice slice of length 4462 03:07:18,760 --> 03:07:22,160 three um and initializes these three 4463 03:07:22,160 --> 03:07:24,760 values into that slice rather than what 4464 03:07:24,760 --> 03:07:26,880 would happen up here which is that we 4465 03:07:26,880 --> 03:07:29,680 create kind of all of the zero values um 4466 03:07:29,680 --> 03:07:31,560 to fill out the slice kind of of the 4467 03:07:31,560 --> 03:07:33,479 given length so this would be a slice of 4468 03:07:33,479 --> 03:07:35,600 five zeros right and then to just point 4469 03:07:35,600 --> 03:07:37,720 out two more things regarding syntax 4470 03:07:37,720 --> 03:07:40,239 there is a built-in length function that 4471 03:07:40,239 --> 03:07:42,319 Returns the length of a slice and a 4472 03:07:42,319 --> 03:07:45,279 built-in cap function that Returns the 4473 03:07:45,279 --> 03:07:47,680 capacity so now that we are experts on 4474 03:07:47,680 --> 03:07:49,880 slices let's jump into the 4475 03:07:49,880 --> 03:07:51,920 assignment says we send a lot of text 4476 03:07:51,920 --> 03:07:53,439 messages at texo and our API is getting 4477 03:07:53,439 --> 03:07:55,279 slow and unresponsive so I just 4478 03:07:55,279 --> 03:07:56,800 mentioned how you probably shouldn't 4479 03:07:56,800 --> 03:07:59,600 worry about performance well here's a 4480 03:07:59,600 --> 03:08:00,439 case where you should worry about 4481 03:08:00,439 --> 03:08:01,800 performance right you shouldn't worry 4482 03:08:01,800 --> 03:08:03,479 about performance until well it starts 4483 03:08:03,479 --> 03:08:05,640 to become a problem so we're starting to 4484 03:08:05,640 --> 03:08:07,720 have a problem with um this memory 4485 03:08:07,720 --> 03:08:10,920 copying being slow so we've been asked 4486 03:08:10,920 --> 03:08:13,359 to preallocate our 4487 03:08:13,359 --> 03:08:17,040 slices it says um if we know the Rough 4488 03:08:17,040 --> 03:08:18,600 Side of the before we fill it up we can 4489 03:08:18,600 --> 03:08:20,120 make our program Faster by creating the 4490 03:08:20,120 --> 03:08:22,000 slice with that size ahead of time all 4491 03:08:22,000 --> 03:08:23,319 right so complete the message get 4492 03:08:23,319 --> 03:08:25,760 message costs function it takes a slice 4493 03:08:25,760 --> 03:08:27,319 of messages and returns a slice of 4494 03:08:27,319 --> 03:08:31,160 message costs FL 64s right reallocate a 4495 03:08:31,160 --> 03:08:32,680 slice for the message cost with the same 4496 03:08:32,680 --> 03:08:34,160 length as the message slice let's go 4497 03:08:34,160 --> 03:08:37,880 ahead and start off with that so 4498 03:08:37,880 --> 03:08:40,120 costs we'll make a new slice and it's 4499 03:08:40,120 --> 03:08:43,120 going to be a slice of float 4500 03:08:43,120 --> 03:08:48,239 64 and a length of length messages right 4501 03:08:48,239 --> 03:08:52,120 same same length cool um now we want to 4502 03:08:52,120 --> 03:08:54,239 fill the co fill the cost slice with 4503 03:08:54,239 --> 03:08:55,920 cost reach message so let's go ahead and 4504 03:08:55,920 --> 03:08:59,680 iterate over each message so for I colum 4505 03:08:59,680 --> 03:09:00,880 equals 4506 03:09:00,880 --> 03:09:04,439 0 I is less than length of 4507 03:09:04,439 --> 03:09:07,439 messages 4508 03:09:09,479 --> 03:09:13,120 i++ let's get the message at that index 4509 03:09:13,120 --> 03:09:15,160 messages 4510 03:09:15,160 --> 03:09:19,960 zero oh not a zero excuse me at 4511 03:09:19,960 --> 03:09:22,399 I okay the cost in the cost slice should 4512 03:09:22,399 --> 03:09:23,439 correspond to the message and the 4513 03:09:23,439 --> 03:09:24,840 message slice at the same index the cost 4514 03:09:24,840 --> 03:09:26,080 of a message is the length of the 4515 03:09:26,080 --> 03:09:29,760 message multiplied by 01 so cost equals 4516 03:09:29,760 --> 03:09:32,760 the length of the message multiplied by 4518 03:09:34,439 --> 03:09:36,960 01 that's going to need to be cast to a 4519 03:09:36,960 --> 03:09:39,200 float 4520 03:09:39,200 --> 03:09:42,520 64 perfect cool and then we just need to 4521 03:09:42,520 --> 03:09:45,439 save that into the costs slice so costs 4522 03:09:45,439 --> 03:09:49,000 at I equals 4523 03:09:49,000 --> 03:09:52,239 cost right correspond with the same 4524 03:09:52,239 --> 03:09:55,640 index and we know that that um that 4525 03:09:55,640 --> 03:09:57,760 index already exists because we 4526 03:09:57,760 --> 03:10:00,760 pre-allocated it to the correct size 4527 03:10:00,760 --> 03:10:03,439 cool so now we can just return costs 4528 03:10:03,439 --> 03:10:06,279 let's go ahead and run 4529 03:10:07,760 --> 03:10:12,359 that and see if these make 4530 03:10:12,399 --> 03:10:15,520 sense okay these costs line up with the 4531 03:10:15,520 --> 03:10:17,399 length of the messages so this is is 4532 03:10:17,399 --> 03:10:18,960 looking good to me let's review the 4533 03:10:18,960 --> 03:10:20,479 difference between the length and the 4534 03:10:20,479 --> 03:10:22,160 capacity of a slice sometimes this can 4535 03:10:22,160 --> 03:10:24,560 be a little bit confusing the length is 4536 03:10:24,560 --> 03:10:26,000 the thing that you're going to care 4537 03:10:26,000 --> 03:10:28,120 about most often the length just tells 4538 03:10:28,120 --> 03:10:30,160 you how many things are in that slice 4539 03:10:30,160 --> 03:10:32,000 right if I have five items then the 4540 03:10:32,000 --> 03:10:34,720 length of the slice is going to be five 4541 03:10:34,720 --> 03:10:35,600 the 4542 03:10:35,600 --> 03:10:39,000 capacity the capacity of a slice reports 4543 03:10:39,000 --> 03:10:41,680 the maximum length the slice can assume 4544 03:10:41,680 --> 03:10:44,000 right before it gets kind of reassigned 4545 03:10:44,000 --> 03:10:46,840 into a new array so capacity is really 4546 03:10:46,840 --> 03:10:48,160 again only something you're going to 4547 03:10:48,160 --> 03:10:49,640 care about if you're worried about 4548 03:10:49,640 --> 03:10:51,920 performance but the length you'll be 4549 03:10:51,920 --> 03:10:53,960 concerned about just for kind of normal 4550 03:10:53,960 --> 03:10:55,479 business logic reasons right just 4551 03:10:55,479 --> 03:10:56,840 because you want to know how many things 4552 03:10:56,840 --> 03:10:59,040 are stored in your slice so to answer 4553 03:10:59,040 --> 03:11:00,840 this question it says what does the cap 4554 03:11:00,840 --> 03:11:03,000 function return answers are the last 4555 03:11:03,000 --> 03:11:05,319 last element of a slice or the maximum 4556 03:11:05,319 --> 03:11:07,680 length the slice of the slice before 4557 03:11:07,680 --> 03:11:09,640 reallocation of the underlying array is 4558 03:11:09,640 --> 03:11:12,520 necessary the answer is going to be the 4559 03:11:12,520 --> 03:11:14,399 maximum length the next question is what 4560 03:11:14,399 --> 03:11:17,000 does the length function return current 4561 03:11:17,000 --> 03:11:18,680 length of the slice or the maximum 4562 03:11:18,680 --> 03:11:19,560 length of the slice before the 4563 03:11:19,560 --> 03:11:22,120 reallocation is necessary and the answer 4564 03:11:22,120 --> 03:11:23,600 is going to be the current length of the 4565 03:11:23,600 --> 03:11:25,640 slice and we haven't really talked about 4566 03:11:25,640 --> 03:11:27,720 this yet but I'll just kind of inform 4567 03:11:27,720 --> 03:11:29,920 you as we answer this question says what 4568 03:11:29,920 --> 03:11:33,600 do length and cap the two functions do 4569 03:11:33,600 --> 03:11:37,120 when a slice is nil do they Panic or 4570 03:11:37,120 --> 03:11:39,200 return zero and the answer is that they 4571 03:11:39,200 --> 03:11:41,000 return zero they are safe functions to 4572 03:11:41,000 --> 03:11:43,640 call um they won't make your code panic 4573 03:11:43,640 --> 03:11:46,279 and error and crash right um I don't 4574 03:11:46,279 --> 03:11:47,479 know how much we've talked about 4575 03:11:47,479 --> 03:11:49,720 panicking up to this point in the course 4576 03:11:49,720 --> 03:11:52,200 but panicking just means runtime error 4577 03:11:52,200 --> 03:11:54,040 that's unrecoverable 4578 03:11:54,040 --> 03:11:56,359 unrecoverable um generally speaking you 4579 03:11:56,359 --> 03:11:58,000 don't want your code panicking and you 4580 03:11:58,000 --> 03:11:59,760 want to write your code in such a way 4581 03:11:59,760 --> 03:12:03,040 that it can't Panic um so again length 4582 03:12:03,040 --> 03:12:05,439 and cap here um are safe they will never 4583 03:12:05,439 --> 03:12:08,920 Panic if um a slice happens to be um the 4584 03:12:08,920 --> 03:12:11,760 zero value which is nil time for some 4585 03:12:11,760 --> 03:12:15,000 vartic functions um this sounds like a 4586 03:12:15,000 --> 03:12:16,840 really complex thing but we've actually 4587 03:12:16,840 --> 03:12:18,880 been using vartic functions up to this 4588 03:12:18,880 --> 03:12:22,279 point in the course because the S printf 4589 03:12:22,279 --> 03:12:24,640 print F print line all of those 4590 03:12:24,640 --> 03:12:27,359 functions are actually vartic so a 4591 03:12:27,359 --> 03:12:29,760 vartic function receives the vartic 4592 03:12:29,760 --> 03:12:31,720 arguments as a slice let's take a look 4593 03:12:31,720 --> 03:12:34,560 at the syntax so here we have a sum 4594 03:12:34,560 --> 03:12:36,880 function and its function signature is 4595 03:12:36,880 --> 03:12:38,080 just maybe a little bit different than 4596 03:12:38,080 --> 03:12:40,000 you're used to basically we have this 4597 03:12:40,000 --> 03:12:44,040 nums uh parameter which is of type dot 4598 03:12:44,040 --> 03:12:48,200 dot do int now here's the thing dot dot 4599 03:12:48,200 --> 03:12:49,040 do 4600 03:12:49,040 --> 03:12:52,200 int as far as the function definition is 4601 03:12:52,200 --> 03:12:55,840 concerned is just a slice we treat this 4602 03:12:55,840 --> 03:12:58,279 just like we would if it said you know 4603 03:12:58,279 --> 03:13:01,359 square brackets int it's it's just a 4604 03:13:01,359 --> 03:13:03,800 slice of integers so you're probably 4605 03:13:03,800 --> 03:13:05,399 sitting there thinking well why can't I 4606 03:13:05,399 --> 03:13:06,880 just use a slice of integers why can't 4607 03:13:06,880 --> 03:13:08,560 we just keep it simple why do we have to 4608 03:13:08,560 --> 03:13:11,520 do everything differently ah okay well 4609 03:13:11,520 --> 03:13:13,840 uh don't don't worry too much um the 4610 03:13:13,840 --> 03:13:16,800 difference is on the caller's side so 4611 03:13:16,800 --> 03:13:18,600 the function definition is the same 4612 03:13:18,600 --> 03:13:20,359 whether you use dot dot dot int or 4613 03:13:20,359 --> 03:13:23,399 square brackets int but if you use a 4614 03:13:23,399 --> 03:13:27,760 vartic function then the calling code so 4615 03:13:27,760 --> 03:13:30,439 the code that uses the sum function can 4616 03:13:30,439 --> 03:13:33,200 actually pass in kind of any number of 4617 03:13:33,200 --> 03:13:35,680 arguments and they'll come into the 4618 03:13:35,680 --> 03:13:37,880 function as a slice of integers so here 4619 03:13:37,880 --> 03:13:42,239 we could call for example sum 1 2 3 and 4620 03:13:42,239 --> 03:13:44,399 the sum function gets a slice of 4621 03:13:44,399 --> 03:13:47,560 integers with you know the values one 4622 03:13:47,560 --> 03:13:50,399 two and three in the first three indexes 4623 03:13:50,399 --> 03:13:53,200 of the slice um this means that the 4624 03:13:53,200 --> 03:13:56,520 caller could also call some one comma 2 4625 03:13:56,520 --> 03:13:58,359 right and we'd have a slice of length 4626 03:13:58,359 --> 03:14:01,080 two so it kind of just gives the collar 4627 03:14:01,080 --> 03:14:03,720 of the function a different syntax um 4628 03:14:03,720 --> 03:14:05,960 and specifically kind of a more flexible 4629 03:14:05,960 --> 03:14:08,600 syntax uh for how they're able to pass 4630 03:14:08,600 --> 03:14:11,239 in sort of a dynamic number of arguments 4631 03:14:11,239 --> 03:14:12,920 into the function now again we've 4632 03:14:12,920 --> 03:14:15,680 already been using vartic functions you 4633 03:14:15,680 --> 03:14:17,960 probably remember the print line 4634 03:14:17,960 --> 03:14:21,040 function right this is how we print text 4635 03:14:21,040 --> 03:14:25,439 to the console um it's a vartic function 4636 03:14:25,439 --> 03:14:28,960 dot dot dot interface right so it can 4637 03:14:28,960 --> 03:14:32,399 take any number of arbitrary inputs and 4638 03:14:32,399 --> 03:14:35,319 it sort of prints them all out with new 4639 03:14:35,319 --> 03:14:38,040 lines in between each element now along 4640 03:14:38,040 --> 03:14:41,319 with vartic function definitions we also 4641 03:14:41,319 --> 03:14:43,760 have another operator called the spread 4642 03:14:43,760 --> 03:14:46,040 operator and the spread operator is kind 4643 03:14:46,040 --> 03:14:47,680 of like the inverse 4644 03:14:47,680 --> 03:14:51,239 of a vartic function by using the spread 4645 03:14:51,239 --> 03:14:55,359 operator we're able to take a slice of 4646 03:14:55,359 --> 03:14:59,399 values and pass them into a vartic 4647 03:14:59,399 --> 03:15:02,279 function so this isn't the intended use 4648 03:15:02,279 --> 03:15:05,120 case 100% of the time otherwise you just 4649 03:15:05,120 --> 03:15:07,160 Define your your function to take a 4650 03:15:07,160 --> 03:15:08,560 slice of strings and you'd pass in a 4651 03:15:08,560 --> 03:15:10,800 slice of strings but if you do have a 4652 03:15:10,800 --> 03:15:13,239 function that is already vartic and you 4653 03:15:13,239 --> 03:15:16,120 want to pass in a slice as the variable 4654 03:15:16,120 --> 03:15:18,319 part then you can use this spread 4655 03:15:18,319 --> 03:15:21,120 operator this trailing dot dot dot to 4656 03:15:21,120 --> 03:15:24,960 sort of spread out in this case this 4657 03:15:24,960 --> 03:15:28,840 name slice into the vartic function 4658 03:15:28,840 --> 03:15:30,600 let's get our hands dirty with this so 4659 03:15:30,600 --> 03:15:32,600 it says we need to sum up the costs of 4660 03:15:32,600 --> 03:15:34,080 all individual messages so that we can 4661 03:15:34,080 --> 03:15:35,640 send an end of Monon Bill to our 4662 03:15:35,640 --> 03:15:38,120 customers complete the sum function so 4663 03:15:38,120 --> 03:15:40,640 that it Returns the sum of all of its 4664 03:15:40,640 --> 03:15:43,880 inputs cool so this is going to be very 4665 03:15:43,880 --> 03:15:46,160 similar to this sum function right the 4666 03:15:46,160 --> 03:15:47,760 the difference here is that we're using 4667 03:15:47,760 --> 03:15:50,080 float 64s and we're going to write it 4668 03:15:50,080 --> 03:15:52,399 from scratch uh so that we get our own 4669 03:15:52,399 --> 03:15:56,520 our own crack at it okay so first things 4670 03:15:56,520 --> 03:15:58,359 first uh let's create kind of the 4671 03:15:58,359 --> 03:16:02,880 default sum which is going to be 4672 03:16:02,880 --> 03:16:07,760 0.0.0 so uh let's say 4673 03:16:07,760 --> 03:16:11,000 total now remember we can treat nums as 4674 03:16:11,000 --> 03:16:15,279 just another slice of float 64s so 4 I 4675 03:16:15,279 --> 03:16:19,520 colon equals 0 I is less than length of 4676 03:16:19,520 --> 03:16:22,520 nums 4677 03:16:22,920 --> 03:16:25,800 i++ total plus 4678 03:16:25,800 --> 03:16:28,520 equals nums at 4679 03:16:28,520 --> 03:16:31,040 I 4680 03:16:31,040 --> 03:16:33,760 right return 4681 03:16:33,760 --> 03:16:37,439 total cool pretty straightforward um 4682 03:16:37,439 --> 03:16:40,199 let's go ahead and run 4683 03:16:41,800 --> 03:16:44,840 that so summing three costs bill for the 4684 03:16:44,840 --> 03:16:47,439 month $6 4685 03:16:47,439 --> 03:16:52,279 5 costs 15 10 costs 55 do these match up 4686 03:16:52,279 --> 03:16:55,359 looks like yep that should be 4687 03:16:55,359 --> 03:16:59,560 six 6 + 4 + 5 that's 6+ 9 that's 15 Yep 4688 03:16:59,560 --> 03:17:00,439 this is looking good I'm going to go 4689 03:17:00,439 --> 03:17:03,239 ahead and submit that now I told you 4690 03:17:03,239 --> 03:17:05,520 that resizing slices is possible we just 4691 03:17:05,520 --> 03:17:07,199 haven't really done it yet um that's 4692 03:17:07,199 --> 03:17:09,560 what the append function is for so the 4693 03:17:09,560 --> 03:17:12,120 built-in append function is actually a 4694 03:17:12,120 --> 03:17:14,239 VAR adic function but it allows us to 4695 03:17:14,239 --> 03:17:16,040 just add new things to the end of a 4696 03:17:16,040 --> 03:17:18,199 slice and automatically takes care of 4697 03:17:18,199 --> 03:17:20,080 adjusting the length and the capacity of 4698 03:17:20,080 --> 03:17:22,520 the slice accordingly right allocating 4699 03:17:22,520 --> 03:17:25,640 new underlying arrays as necessary now 4700 03:17:25,640 --> 03:17:29,000 here are your syntax options for using 4701 03:17:29,000 --> 03:17:30,880 the append function if you just want to 4702 03:17:30,880 --> 03:17:32,399 append one thing then you'll use this 4703 03:17:32,399 --> 03:17:34,120 top option let's say we have a slice 4704 03:17:34,120 --> 03:17:36,199 called slice we want to append a 4705 03:17:36,199 --> 03:17:37,920 variable called one thing to it 4706 03:17:37,920 --> 03:17:40,880 basically we call the append function we 4707 03:17:40,880 --> 03:17:43,239 pass in the slice we want to append to 4708 03:17:43,239 --> 03:17:46,120 as the first uh item we pass the 4709 03:17:46,120 --> 03:17:48,000 variable that we want to append onto the 4710 03:17:48,000 --> 03:17:50,199 end as the next thing and then we 4711 03:17:50,199 --> 03:17:54,120 reassign back into that same slice now 4712 03:17:54,120 --> 03:17:56,880 because append is a vartic function we 4713 03:17:56,880 --> 03:17:59,760 can append multiple things right so um 4714 03:17:59,760 --> 03:18:01,640 if we want to append the first thing and 4715 03:18:01,640 --> 03:18:03,680 then the second thing after that um we 4716 03:18:03,680 --> 03:18:05,319 could do it like this and obviously we 4717 03:18:05,319 --> 03:18:07,479 could also use the spread operator if we 4718 03:18:07,479 --> 03:18:10,880 want to to be 100% honest though 99% of 4719 03:18:10,880 --> 03:18:12,479 the time you'll be using this first one 4720 03:18:12,479 --> 03:18:14,000 because you'll just be appending items 4721 03:18:14,000 --> 03:18:15,479 one at a time let's hop into the 4722 03:18:15,479 --> 03:18:17,399 assignment it says we've been asked to 4723 03:18:17,399 --> 03:18:20,520 bucket costs for an entire month into 4724 03:18:20,520 --> 03:18:23,520 the costs that occurred on each day of 4725 03:18:23,520 --> 03:18:26,279 the month so complete the get cost by 4726 03:18:26,279 --> 03:18:28,199 day function it to return a slice of 4727 03:18:28,199 --> 03:18:30,319 float 64s where each element is the 4728 03:18:30,319 --> 03:18:32,239 total cost for that day okay so we have 4729 03:18:32,239 --> 03:18:34,279 like this giant list of costs and we 4730 03:18:34,279 --> 03:18:37,359 need to kind of uh condense all the 4731 03:18:37,359 --> 03:18:39,600 costs that happened on a specific day 4732 03:18:39,600 --> 03:18:43,199 into one index for that day makes sense 4733 03:18:43,199 --> 03:18:45,479 to me the length of the slice should be 4734 03:18:45,479 --> 03:18:47,279 equal to the number of days represented 4735 03:18:47,279 --> 03:18:50,239 in the costs 4736 03:18:50,239 --> 03:18:53,000 slice including any days that have no 4737 03:18:53,000 --> 03:18:55,680 costs up to the last day represented in 4738 03:18:55,680 --> 03:18:58,040 the slice Okay cool so if we have costs 4739 03:18:58,040 --> 03:19:00,560 just for say the first month or the 4740 03:19:00,560 --> 03:19:02,080 first day of the month and the fifth day 4741 03:19:02,080 --> 03:19:04,479 of the month then we should have um kind 4742 03:19:04,479 --> 03:19:07,920 of five indexes in our resulting array 4743 03:19:07,920 --> 03:19:09,720 with kind of a non-zero value in the 4744 03:19:09,720 --> 03:19:12,319 first and the fifth indexes zeros in the 4745 03:19:12,319 --> 03:19:15,399 middle and nothing after that okay here 4746 03:19:15,399 --> 03:19:18,560 we've got an example 4747 03:19:18,560 --> 03:19:23,040 um given this input so day cost so we 4748 03:19:23,040 --> 03:19:26,720 have costs on days on days 0o one and 4749 03:19:26,720 --> 03:19:30,080 five this would be the resulting array 4750 03:19:30,080 --> 03:19:34,520 right $4 on the first day 5.2 on the 4751 03:19:34,520 --> 03:19:37,399 second day because we sum those right 4752 03:19:37,399 --> 03:19:39,520 and then on that last day we'd have 4753 03:19:39,520 --> 03:19:43,239 2.5 cool let's write the 4754 03:19:43,239 --> 03:19:45,560 function so first things first we're 4755 03:19:45,560 --> 03:19:47,239 going to need 4756 03:19:47,239 --> 03:19:50,120 um we're going to need a slice to append 4757 03:19:50,120 --> 03:19:56,760 into so costs by day we'll make a new uh 4758 03:19:56,760 --> 03:20:00,199 a new slice of float 64 and here I'm 4759 03:20:00,199 --> 03:20:03,160 just using the slice literal syntax um 4760 03:20:03,160 --> 03:20:05,319 instead of the make function they're 4761 03:20:05,319 --> 03:20:07,640 pretty dang 4762 03:20:07,640 --> 03:20:09,840 similar now we're probably going to want 4763 03:20:09,840 --> 03:20:14,160 to iterate over all of the cost so for I 4764 03:20:14,160 --> 03:20:17,760 equals 0 I is less than length 4765 03:20:17,760 --> 03:20:20,760 costs 4766 03:20:24,920 --> 03:20:27,520 i++ costs at 4767 03:20:27,520 --> 03:20:32,120 I okay so a cost is this structure here 4768 03:20:32,120 --> 03:20:34,760 and we can take a look at the day 4769 03:20:34,760 --> 03:20:38,439 there um we're going to need to figure 4770 03:20:38,439 --> 03:20:41,680 out basically when we're appending to 4771 03:20:41,680 --> 03:20:45,080 this costs by day slice and when we're 4772 03:20:45,080 --> 03:20:47,960 just adding to an existing index so I 4773 03:20:47,960 --> 03:20:50,199 think the easiest thing to do would 4774 03:20:50,199 --> 03:20:51,720 basically be to 4775 03:20:51,720 --> 03:20:55,239 say um 4776 03:20:55,640 --> 03:20:59,239 if day is greater than the length of 4777 03:20:59,239 --> 03:21:02,560 costs by 4778 03:21:03,479 --> 03:21:06,760 day actually it's going to be a four so 4779 03:21:06,760 --> 03:21:09,720 like while the day is greater than the 4780 03:21:09,720 --> 03:21:11,279 length of cost by day we're going to 4781 03:21:11,279 --> 03:21:15,479 append cost by day equals append cost by 4782 03:21:15,479 --> 03:21:18,319 day 4783 03:21:18,319 --> 03:21:21,160 0.0 right so in effect this for Loop 4784 03:21:21,160 --> 03:21:25,160 here just says if I've encountered a day 4785 03:21:25,160 --> 03:21:28,160 that I don't yet have room for I'm going 4786 03:21:28,160 --> 03:21:31,600 to grow the slice by just appending 4787 03:21:31,600 --> 03:21:34,880 zeros until I have enough room so once 4788 03:21:34,880 --> 03:21:37,560 we're done with that Loop we should be 4789 03:21:37,560 --> 03:21:40,399 able to assign directly into the costs 4790 03:21:40,399 --> 03:21:41,439 by 4791 03:21:41,439 --> 03:21:44,359 day I basically saying cost by day plus 4792 03:21:44,359 --> 03:21:47,359 equals 4793 03:21:49,560 --> 03:21:51,000 cost. 4794 03:21:51,000 --> 03:21:54,279 value right because it starts at zero so 4795 03:21:54,279 --> 03:21:56,399 then we can just 4796 03:21:56,399 --> 03:22:00,760 add we just add the cost and again if if 4797 03:22:00,760 --> 03:22:02,800 the day is less than cost by day then we 4798 03:22:02,800 --> 03:22:04,760 just don't do this step we just skip 4799 03:22:04,760 --> 03:22:07,239 over this for Loop so that's looking 4800 03:22:07,239 --> 03:22:08,840 correct to me I'm going to go ahead and 4801 03:22:08,840 --> 03:22:12,319 return costs by 4802 03:22:12,319 --> 03:22:16,199 day and let's run that code see what we 4803 03:22:16,199 --> 03:22:22,080 get undefined day what did I screw up 4804 03:22:22,560 --> 03:22:27,640 here yeah needs to be cost. day right 4805 03:22:27,640 --> 03:22:28,920 access that 4806 03:22:28,920 --> 03:22:31,600 field invalid operation cost by day plus 4807 03:22:31,600 --> 03:22:34,800 equals cost. value so cost. value is a 4808 03:22:34,800 --> 03:22:35,680 float 4809 03:22:35,680 --> 03:22:38,439 64 costs by 4810 03:22:38,439 --> 03:22:42,800 day is a slice of flow 4811 03:22:42,800 --> 03:22:45,600 64s right because this is a slice so 4812 03:22:45,600 --> 03:22:47,040 costs by 4813 03:22:47,040 --> 03:22:50,040 a 4814 03:22:51,479 --> 03:22:54,560 at at cost. 4815 03:22:54,560 --> 03:22:57,560 day 4816 03:22:57,800 --> 03:23:00,239 right right because our the slice that 4817 03:23:00,239 --> 03:23:00,960 we're 4818 03:23:00,960 --> 03:23:05,600 returning um the indexes in each or the 4819 03:23:05,600 --> 03:23:07,239 indexes of the slice represent each day 4820 03:23:07,239 --> 03:23:09,080 in the month so we need to index back 4821 03:23:09,080 --> 03:23:10,399 into the 4822 03:23:10,399 --> 03:23:14,319 day okay try 4823 03:23:14,319 --> 03:23:18,080 that whoa what do we got 4824 03:23:18,080 --> 03:23:20,199 Panic runtime error index out of range 4825 03:23:20,199 --> 03:23:21,960 zero with length 4826 03:23:21,960 --> 03:23:24,000 zero 4827 03:23:24,000 --> 03:23:26,760 okay what did we screw 4828 03:23:26,760 --> 03:23:29,760 up 4829 03:23:30,439 --> 03:23:36,000 so somewhere we are indexing into a 4830 03:23:36,000 --> 03:23:39,680 slice where the value doesn't like the 4831 03:23:39,680 --> 03:23:41,479 the the index that we're indexing with 4832 03:23:41,479 --> 03:23:43,560 is outside the range of the slice so um 4833 03:23:43,560 --> 03:23:45,000 we haven't really talked about this this 4834 03:23:45,000 --> 03:23:46,680 is probably great that we ran into this 4835 03:23:46,680 --> 03:23:51,880 bug um if you try to index which is this 4836 03:23:51,880 --> 03:23:53,920 operation here so like this is indexing 4837 03:23:53,920 --> 03:23:55,960 into index five right but here we're 4838 03:23:55,960 --> 03:23:58,640 indexing into cost. day which holds an 4839 03:23:58,640 --> 03:24:01,680 integer um if you try to index into an 4840 03:24:01,680 --> 03:24:04,279 index that is outside the length of the 4841 03:24:04,279 --> 03:24:06,399 slice so you have a slice of length say 4842 03:24:06,399 --> 03:24:09,960 three and you try to access index six 4843 03:24:09,960 --> 03:24:11,920 then you'll encounter this error that 4844 03:24:11,920 --> 03:24:14,439 that's what we're seeing here so it 4845 03:24:14,439 --> 03:24:17,080 looks like that's what we are doing 4846 03:24:17,080 --> 03:24:21,479 so for cost. day is greater than the 4847 03:24:21,479 --> 03:24:24,560 length now let's think about that if the 4848 03:24:24,560 --> 03:24:29,120 day is five and the length is 4849 03:24:29,120 --> 03:24:33,120 five we are not going to do our growth 4850 03:24:33,120 --> 03:24:35,160 so I'm actually I think I have an off by 4851 03:24:35,160 --> 03:24:38,239 one error here right I actually what I 4852 03:24:38,239 --> 03:24:42,040 actually want to do is say if the cost 4853 03:24:42,040 --> 03:24:44,239 if the if the cost. day is greater than 4854 03:24:44,239 --> 03:24:48,800 or equal to the length right because an 4855 03:24:48,800 --> 03:24:52,359 array or a slice of length four actually 4856 03:24:52,359 --> 03:24:54,160 only has 4857 03:24:54,160 --> 03:24:57,160 three um kind of indexes I mean it has 4858 03:24:57,160 --> 03:24:59,040 four indexes but they start at zero so 4859 03:24:59,040 --> 03:25:01,720 like length four the indexes are 0 1 2 4860 03:25:01,720 --> 03:25:04,160 and three right let's go ahead and run 4861 03:25:04,160 --> 03:25:05,680 that 4862 03:25:05,680 --> 03:25:10,199 again cool no more 4863 03:25:11,040 --> 03:25:15,479 Panic day one $1 or day Zero $1 day one 4864 03:25:15,479 --> 03:25:19,319 510 day 2 250 let's see if that lines up 4865 03:25:19,319 --> 03:25:21,840 with the test 4866 03:25:23,960 --> 03:25:26,439 Suite so here it looks like Day Zero 4867 03:25:26,439 --> 03:25:29,640 should have one day one should have yep 4868 03:25:29,640 --> 03:25:32,479 5.1 if we add those together and day 3 4869 03:25:32,479 --> 03:25:35,880 should have 5 point what's that 4870 03:25:35,880 --> 03:25:39,319 6.3 yep 6.3 okay this is looking correct 4871 03:25:39,319 --> 03:25:40,520 to 4872 03:25:40,520 --> 03:25:44,199 me slices can hold other slices right 4873 03:25:44,199 --> 03:25:48,880 this kind of creates a 2d Matrix um of 4874 03:25:48,880 --> 03:25:52,800 values right so for example here a 10x10 4875 03:25:52,800 --> 03:25:54,760 Matrix of integers would look something 4876 03:25:54,760 --> 03:25:57,720 like this where the First Slice is just 4877 03:25:57,720 --> 03:26:01,560 a slice of slices hopefully that makes 4878 03:26:01,560 --> 03:26:03,680 some amount of sense if not don't worry 4879 03:26:03,680 --> 03:26:05,439 we'll get into the assignment here in 4880 03:26:05,439 --> 03:26:07,800 just a second so it says we support 4881 03:26:07,800 --> 03:26:10,080 various graphs and dashboards on Tex 4882 03:26:10,080 --> 03:26:11,760 that display message analytics for our 4883 03:26:11,760 --> 03:26:14,080 users the UI for our graphs and charts 4884 03:26:14,080 --> 03:26:16,359 is built on top of a grid system let's 4885 03:26:16,359 --> 03:26:18,239 build that grid logic so this is super 4886 03:26:18,239 --> 03:26:19,880 common in graphics development right 4887 03:26:19,880 --> 03:26:22,239 we're kind of building on 2D screens so 4888 03:26:22,239 --> 03:26:25,720 we need sort of an X and A Y um cell 4889 03:26:25,720 --> 03:26:27,920 within a matrix which is again often 4890 03:26:27,920 --> 03:26:30,600 represented as a slice of slices the 4891 03:26:30,600 --> 03:26:32,520 assignment says complete the create 4892 03:26:32,520 --> 03:26:34,479 Matrix function it takes a number of 4893 03:26:34,479 --> 03:26:36,960 rows and columns and returns a 2d slice 4894 03:26:36,960 --> 03:26:38,600 of integers where the value of each cell 4895 03:26:38,600 --> 03:26:42,160 is I * J where I and J are the indexes 4896 03:26:42,160 --> 03:26:44,640 of the row and column 4897 03:26:44,640 --> 03:26:47,960 respectively okay cool so create Matrix 4898 03:26:47,960 --> 03:26:50,520 we get two integers representing how big 4899 03:26:50,520 --> 03:26:52,000 we want the Matrix to be and we just 4900 03:26:52,000 --> 03:26:55,680 have to return the Matrix Okay 4901 03:26:55,680 --> 03:26:57,439 cool 4902 03:26:57,439 --> 03:27:00,279 so let's go ahead and start building 4903 03:27:00,279 --> 03:27:03,840 that out first we need to create um or 4904 03:27:03,840 --> 03:27:07,319 initialize the Matrix so let's say 4905 03:27:07,319 --> 03:27:10,800 Matrix slice let's use make make slice 4906 03:27:10,800 --> 03:27:13,000 slice 4907 03:27:13,000 --> 03:27:16,520 in right and we can just initialize it 4908 03:27:16,520 --> 03:27:18,520 to a length of zero it doesn't matter 4909 03:27:18,520 --> 03:27:22,680 we're going to grow it and four I col 4910 03:27:22,680 --> 03:27:27,359 equals 0 I is less than length of 4911 03:27:27,359 --> 03:27:30,120 rows 4912 03:27:30,120 --> 03:27:31,960 i++ and then we're going to need an 4913 03:27:31,960 --> 03:27:33,600 inner for 4914 03:27:33,600 --> 03:27:38,199 Loop manage J which is going 4915 03:27:38,199 --> 03:27:41,640 to deal with the number of columns 4916 03:27:41,640 --> 03:27:43,840 columns 4917 03:27:43,840 --> 03:27:47,160 j++ okay so what do we do 4918 03:27:47,160 --> 03:27:49,199 um when we get to the first row well the 4919 03:27:49,199 --> 03:27:52,199 first thing we need to do is make a new 4920 03:27:52,199 --> 03:27:56,439 slice to represent the row so we'll say 4921 03:27:56,439 --> 03:27:59,960 row make and we can just 4922 03:27:59,960 --> 03:28:04,439 do a a single slice of integers again 4923 03:28:04,439 --> 03:28:08,800 row uh length of Zer is fine um we could 4924 03:28:08,800 --> 03:28:11,040 pre-allocate but it probably doesn't 4925 03:28:11,040 --> 03:28:12,680 matter too much at this 4926 03:28:12,680 --> 03:28:17,080 point um and then for each J a we're now 4927 03:28:17,080 --> 03:28:19,040 going to append into the row so we do 4928 03:28:19,040 --> 03:28:22,680 row equals 4929 03:28:22,680 --> 03:28:24,199 append 4930 03:28:24,199 --> 03:28:28,040 row I * J I believe was the formula 4931 03:28:28,040 --> 03:28:31,760 right we want every cell to be the 4932 03:28:31,760 --> 03:28:35,399 result of I * J so the values will sort 4933 03:28:35,399 --> 03:28:38,199 of grow out um as the Matrix gets larger 4934 03:28:38,199 --> 03:28:39,600 and 4935 03:28:39,600 --> 03:28:42,880 larger cool so that's adding the like 4936 03:28:42,880 --> 03:28:46,520 this inner loop is adding values to each 4937 03:28:46,520 --> 03:28:48,800 individual row and then we just need to 4938 03:28:48,800 --> 03:28:51,000 append the row to The Matrix so 4939 03:28:51,000 --> 03:28:55,359 Matrix equals append 4940 03:28:55,359 --> 03:28:57,000 Matrix 4941 03:28:57,000 --> 03:28:59,120 row and then when we're done appending 4942 03:28:59,120 --> 03:29:00,560 all of the rows to The Matrix we can 4943 03:29:00,560 --> 03:29:03,160 return the Matrix 4944 03:29:03,160 --> 03:29:06,000 itself go aad and run 4945 03:29:06,000 --> 03:29:08,840 that invalid argument row variable of 4946 03:29:08,840 --> 03:29:12,840 type int for length see what we got 4947 03:29:12,840 --> 03:29:16,840 here where did I screw up 4948 03:29:16,840 --> 03:29:19,160 this time 4949 03:29:19,160 --> 03:29:21,600 right I don't know why I'm checking a 4950 03:29:21,600 --> 03:29:25,880 length here Rose is just an integer it's 4951 03:29:25,880 --> 03:29:31,279 not a slice with a size let's try that 4952 03:29:32,040 --> 03:29:35,120 again cool creating a 3X3 4953 03:29:35,120 --> 03:29:37,880 Matrix does that math check 4954 03:29:37,880 --> 03:29:43,279 out 1 * 1 is 1 1 * 2 is 2 2 * 2 is 4 yep 4955 03:29:43,279 --> 03:29:47,399 that looks good cool let's submit it I 4956 03:29:47,399 --> 03:29:49,760 want to show you a common Pitfall that 4957 03:29:49,760 --> 03:29:52,160 you might fall into uh when dealing with 4958 03:29:52,160 --> 03:29:53,479 slices and how you can just outright 4959 03:29:53,479 --> 03:29:57,239 avoid it um this is something you should 4960 03:29:57,239 --> 03:30:00,359 pretty much never do when you want to 4961 03:30:00,359 --> 03:30:04,199 append to um other slice in this case 4962 03:30:04,199 --> 03:30:06,319 you want to append elements to other 4963 03:30:06,319 --> 03:30:09,600 slice you should always reassign into 4964 03:30:09,600 --> 03:30:12,279 the same slice so this should read other 4965 03:30:12,279 --> 03:30:15,199 slice equals append other slice element 4966 03:30:15,199 --> 03:30:17,680 you don't want to be pending um kind of 4967 03:30:17,680 --> 03:30:20,680 into one thing and reassigning into a 4968 03:30:20,680 --> 03:30:23,279 separate slice you'll run into some bugs 4969 03:30:23,279 --> 03:30:24,720 and we're going to talk about how that 4970 03:30:24,720 --> 03:30:27,560 works right now so in this first example 4971 03:30:27,560 --> 03:30:31,600 we have these slices a b and c and by 4972 03:30:31,600 --> 03:30:33,319 the way I would highly recommend coming 4973 03:30:33,319 --> 03:30:35,239 here on bootd so that you can actually 4974 03:30:35,239 --> 03:30:37,120 kind of look and puzzle through what's 4975 03:30:37,120 --> 03:30:38,760 going on in the code rather than just 4976 03:30:38,760 --> 03:30:41,319 seeing it on the screen um but basically 4977 03:30:41,319 --> 03:30:44,800 we have these slices and when we append 4978 03:30:44,800 --> 03:30:46,439 to them 4979 03:30:46,439 --> 03:30:48,680 we're we're breaking the rule basically 4980 03:30:48,680 --> 03:30:52,239 we're uh appending for example here um 4981 03:30:52,239 --> 03:30:56,199 four onto a but then returning the 4982 03:30:56,199 --> 03:30:59,120 value the value returned by a pend we're 4983 03:30:59,120 --> 03:31:00,760 kind of saving it into a new slice 4984 03:31:00,760 --> 03:31:02,720 called B which again you you generally 4985 03:31:02,720 --> 03:31:04,319 should not do you should just save it 4986 03:31:04,319 --> 03:31:08,120 back into the same slice a um but 4987 03:31:08,120 --> 03:31:09,960 anyways we're going along um kind of 4988 03:31:09,960 --> 03:31:13,399 doing that pattern and at the end you'll 4989 03:31:13,399 --> 03:31:15,439 notice that nothing too terrible 4990 03:31:15,439 --> 03:31:18,000 happened um basically we ended up with 4991 03:31:18,000 --> 03:31:20,800 an a with three zeros B had four 4992 03:31:20,800 --> 03:31:24,880 appended to it properly and C had five 4993 03:31:24,880 --> 03:31:26,560 appended to it properly so you could 4994 03:31:26,560 --> 03:31:28,359 kind of take away from this example well 4995 03:31:28,359 --> 03:31:30,319 maybe there's nothing wrong maybe we can 4996 03:31:30,319 --> 03:31:33,680 just kind of uh break the rule and 4997 03:31:33,680 --> 03:31:36,000 append into new slices seems like 4998 03:31:36,000 --> 03:31:37,960 everything's working like I'd expect and 4999 03:31:37,960 --> 03:31:39,880 it's worth pointing out that we can even 5000 03:31:39,880 --> 03:31:43,800 print out the addresses in memory of the 5001 03:31:43,800 --> 03:31:47,319 slices B and C and see the addresses are 5002 03:31:47,319 --> 03:31:49,680 different in other words when we called 5003 03:31:49,680 --> 03:31:51,880 this append functions where we append 5004 03:31:51,880 --> 03:31:57,199 five onto um you know the slice a and 5005 03:31:57,199 --> 03:31:59,760 save it back into the variable C we can 5006 03:31:59,760 --> 03:32:01,560 see that actually C is being kind of 5007 03:32:01,560 --> 03:32:04,359 copied into a new location so again 5008 03:32:04,359 --> 03:32:06,120 everything's kind of working as we'd 5009 03:32:06,120 --> 03:32:08,439 expect now it's really in this example 5010 03:32:08,439 --> 03:32:12,439 two that something very strange happens 5011 03:32:12,439 --> 03:32:14,000 if we look 5012 03:32:14,000 --> 03:32:17,680 down here we're a pending onto 5013 03:32:17,680 --> 03:32:21,279 J the value four and then we're 5014 03:32:21,279 --> 03:32:26,720 appending onto G here the value five but 5015 03:32:26,720 --> 03:32:29,359 the interesting thing is that after we 5016 03:32:29,359 --> 03:32:33,520 append five to G if we print out J again 5017 03:32:33,520 --> 03:32:36,520 we can see that J was actually changed 5018 03:32:36,520 --> 03:32:40,319 kind of under the hood right up here J 5019 03:32:40,319 --> 03:32:43,399 had four in its fourth 5020 03:32:43,399 --> 03:32:46,279 index and then we never touched J again 5021 03:32:46,279 --> 03:32:49,399 directly but by appending onto G we 5022 03:32:49,399 --> 03:32:53,600 actually screwed up J we mutated J and 5023 03:32:53,600 --> 03:32:55,920 the reason for that is because in this 5024 03:32:55,920 --> 03:32:57,479 example because of the way we've 5025 03:32:57,479 --> 03:33:01,399 sloppily used the append function G and 5026 03:33:01,399 --> 03:33:04,439 J actually point to the same address in 5027 03:33:04,439 --> 03:33:09,880 memory so mutating G changed J now I 5028 03:33:09,880 --> 03:33:11,520 already mentioned that we were doing the 5029 03:33:11,520 --> 03:33:13,760 same thing up here right we were using 5030 03:33:13,760 --> 03:33:15,960 the same kind of sloppy use of the a 5031 03:33:15,960 --> 03:33:17,840 pend function that I'm recommending to 5032 03:33:17,840 --> 03:33:20,800 avoid but we only had the bug in example 5033 03:33:20,800 --> 03:33:24,080 two and the reason for that is because 5034 03:33:24,080 --> 03:33:27,279 the original slice in example two has a 5035 03:33:27,279 --> 03:33:28,560 capacity of 5036 03:33:28,560 --> 03:33:31,920 eight while the original slice in 5037 03:33:31,920 --> 03:33:34,880 example one had a capacity of three so 5038 03:33:34,880 --> 03:33:37,520 what that means is when we used the 5039 03:33:37,520 --> 03:33:40,520 append function in the first example 5040 03:33:40,520 --> 03:33:42,680 once we went over the capacity we 5041 03:33:42,680 --> 03:33:44,960 allocated a new underlying array which 5042 03:33:44,960 --> 03:33:47,560 is why we got different memory addresses 5043 03:33:47,560 --> 03:33:50,800 and so when we mutate C here C is in a 5044 03:33:50,800 --> 03:33:53,120 different place in memory than b so 5045 03:33:53,120 --> 03:33:55,199 they're kind of operating independently 5046 03:33:55,199 --> 03:33:57,160 which is again what you usually want in 5047 03:33:57,160 --> 03:33:58,560 your 5048 03:33:58,560 --> 03:34:01,359 code however because the capacity was 5049 03:34:01,359 --> 03:34:03,720 already large enough in example two 5050 03:34:03,720 --> 03:34:06,000 there was no need for the append 5051 03:34:06,000 --> 03:34:07,520 function to create a new underlying 5052 03:34:07,520 --> 03:34:11,560 array so G and J point to the same the 5053 03:34:11,560 --> 03:34:14,760 same array in memory again which means 5054 03:34:14,760 --> 03:34:17,000 if we mutate G under the hood we just 5055 03:34:17,000 --> 03:34:20,399 mutating J so again the way you can 5056 03:34:20,399 --> 03:34:22,479 avoid all of this 5057 03:34:22,479 --> 03:34:26,359 headache is to just not do this right 5058 03:34:26,359 --> 03:34:30,040 append onto the same slice pretty much 5059 03:34:30,040 --> 03:34:32,279 every time unless you have like some 5060 03:34:32,279 --> 03:34:35,080 crazy specific reason not to do so which 5061 03:34:35,080 --> 03:34:37,680 like I'm skeptical that exists I 5062 03:34:37,680 --> 03:34:39,800 certainly haven't run into it in you 5063 03:34:39,800 --> 03:34:41,600 know many years of writing application 5064 03:34:41,600 --> 03:34:45,359 code in go so the question for this quiz 5065 03:34:45,359 --> 03:34:48,319 is why is five the final value in the 5066 03:34:48,319 --> 03:34:52,439 last index of array J right so why why 5067 03:34:52,439 --> 03:34:54,399 did we have a five here even though we 5068 03:34:54,399 --> 03:34:57,600 appended for um and the answers are J 5069 03:34:57,600 --> 03:34:59,880 and G point to the same underlying array 5070 03:34:59,880 --> 03:35:02,359 so G is aend over OJ the go team is 5071 03:35:02,359 --> 03:35:04,960 trolling I think that's obviously not it 5072 03:35:04,960 --> 03:35:06,359 uh and because a pend only works 5073 03:35:06,359 --> 03:35:07,640 properly when the number of elements is 5074 03:35:07,640 --> 03:35:09,800 less than 10 uh that would be very silly 5075 03:35:09,800 --> 03:35:12,680 so it's it's definitely this middle one 5076 03:35:12,680 --> 03:35:15,120 we're overwriting the same location in 5077 03:35:15,120 --> 03:35:17,520 memory next question on the same topic 5078 03:35:17,520 --> 03:35:19,840 is why doesn't the bug regarding slices 5079 03:35:19,840 --> 03:35:23,880 J and G in example two occur in example 5080 03:35:23,880 --> 03:35:26,920 one as well and the the answers are 5081 03:35:26,920 --> 03:35:28,279 because there are fewer elements and 5082 03:35:28,279 --> 03:35:29,920 goes runtime can't handle more than 5083 03:35:29,920 --> 03:35:32,920 eight elements that would be awful um or 5084 03:35:32,920 --> 03:35:34,800 the array's cap is exceeded so a new 5085 03:35:34,800 --> 03:35:36,920 underlying array is allocated and and 5086 03:35:36,920 --> 03:35:39,000 that one is the answer so the next 5087 03:35:39,000 --> 03:35:41,239 question is how can you best avoid these 5088 03:35:41,239 --> 03:35:43,560 types of bugs don't use the append 5089 03:35:43,560 --> 03:35:45,399 function always assign the result of the 5090 03:35:45,399 --> 03:35:46,880 append pend function back into the same 5091 03:35:46,880 --> 03:35:49,120 slice or always assign the result of the 5092 03:35:49,120 --> 03:35:52,000 append function to a new slice well it's 5093 03:35:52,000 --> 03:35:53,920 not using a new slice that's how we got 5094 03:35:53,920 --> 03:35:55,680 into this trouble in the first place and 5095 03:35:55,680 --> 03:35:57,120 we definitely want to use the append 5096 03:35:57,120 --> 03:35:59,640 function it's pretty useful so again 5097 03:35:59,640 --> 03:36:01,479 always assign the result of the append 5098 03:36:01,479 --> 03:36:04,199 function back into the same slice you'll 5099 03:36:04,199 --> 03:36:06,439 avoid a lot of headache that way finally 5100 03:36:06,439 --> 03:36:09,399 some syntactic sugar to help us iterate 5101 03:36:09,399 --> 03:36:11,760 over the elements of a slice you've 5102 03:36:11,760 --> 03:36:13,640 probably been wondering for the majority 5103 03:36:13,640 --> 03:36:15,880 of this chapter uh do I have to do this 5104 03:36:15,880 --> 03:36:18,720 I equals z i is less than the length 5105 03:36:18,720 --> 03:36:20,120 every time I want to iterate over the 5106 03:36:20,120 --> 03:36:22,000 elements of the slice other languages 5107 03:36:22,000 --> 03:36:24,160 have syntactic sugar to make it easier 5108 03:36:24,160 --> 03:36:26,840 so does go so the syntax is pretty 5109 03:36:26,840 --> 03:36:29,439 simple um this is it right here and 5110 03:36:29,439 --> 03:36:31,960 basically by writing it this way index 5111 03:36:31,960 --> 03:36:33,800 at each iteration of the loop will be 5112 03:36:33,800 --> 03:36:35,680 equal to the index in the loop starting 5113 03:36:35,680 --> 03:36:38,560 at zero right so 0 1 2 3 and then 5114 03:36:38,560 --> 03:36:41,000 element is the value associated with 5115 03:36:41,000 --> 03:36:42,560 that Index right and then obviously 5116 03:36:42,560 --> 03:36:44,840 slice here is the name of the slice so 5117 03:36:44,840 --> 03:36:46,040 range is a real 5118 03:36:46,040 --> 03:36:48,120 the interesting keyword that allows us 5119 03:36:48,120 --> 03:36:50,359 to iterate over everything stored in a 5120 03:36:50,359 --> 03:36:53,399 slice to give a more concrete example 5121 03:36:53,399 --> 03:36:55,439 here we have a slice of strings called 5122 03:36:55,439 --> 03:36:57,880 fruits and we can arrange over the 5123 03:36:57,880 --> 03:37:01,319 fruits and if we print I and fruit in 5124 03:37:01,319 --> 03:37:04,319 this example that we print zero apple 5125 03:37:04,319 --> 03:37:07,840 one banana two grape and so on let's 5126 03:37:07,840 --> 03:37:09,800 jump into the assignment it says we need 5127 03:37:09,800 --> 03:37:12,080 to be able to quickly detect bad words 5128 03:37:12,080 --> 03:37:14,439 in the messages that our system sends 5129 03:37:14,439 --> 03:37:15,840 complete the index of first first bad 5130 03:37:15,840 --> 03:37:18,880 word function okay so that's this um it 5131 03:37:18,880 --> 03:37:20,960 finds any bad words in the message if it 5132 03:37:20,960 --> 03:37:22,800 finds any bad words in the message it 5133 03:37:22,800 --> 03:37:25,239 should return the index of the first bad 5134 03:37:25,239 --> 03:37:27,160 word in the message slice this will help 5135 03:37:27,160 --> 03:37:29,040 us filter out naughty words uh from our 5136 03:37:29,040 --> 03:37:30,560 messaging system if no bad words are 5137 03:37:30,560 --> 03:37:32,439 found will return negative one instead 5138 03:37:32,439 --> 03:37:34,199 use the range 5139 03:37:34,199 --> 03:37:37,399 keyword Okay cool so the bad words 5140 03:37:37,399 --> 03:37:39,520 themselves are defined for us and passed 5141 03:37:39,520 --> 03:37:41,560 into our function and then the message 5142 03:37:41,560 --> 03:37:44,199 itself is already broken up into words 5143 03:37:44,199 --> 03:37:46,239 it looks like and passed in is an array 5144 03:37:46,239 --> 03:37:48,239 of strings right so we can I'm kind of 5145 03:37:48,239 --> 03:37:50,319 just figuring this out by looking uh 5146 03:37:50,319 --> 03:37:52,520 looking down here so we have a slice of 5147 03:37:52,520 --> 03:37:55,720 bad words and a slice of words in the 5148 03:37:55,720 --> 03:37:59,680 message hey there John Okay 5149 03:37:59,680 --> 03:38:03,600 cool so um let's 5150 03:38:03,600 --> 03:38:07,199 start by iterating over all of the words 5151 03:38:07,199 --> 03:38:08,960 in the message right seems like a 5152 03:38:08,960 --> 03:38:12,239 reasonable place to start so 5153 03:38:12,239 --> 03:38:19,680 for I word colon equals range 5154 03:38:19,680 --> 03:38:22,479 message and then we want to check and 5155 03:38:22,479 --> 03:38:25,479 see 5156 03:38:25,479 --> 03:38:29,399 if if one of these words is equal to one 5157 03:38:29,399 --> 03:38:30,960 of the bad words so we're going to use a 5158 03:38:30,960 --> 03:38:33,840 nested Loop 5159 03:38:33,840 --> 03:38:36,479 actually we'll do 5160 03:38:36,479 --> 03:38:40,760 J bad word in range bad 5161 03:38:40,760 --> 03:38:44,399 words right and then here we can say if 5162 03:38:44,399 --> 03:38:47,640 word equals equals bad 5163 03:38:47,640 --> 03:38:50,560 word that means we found the bad word 5164 03:38:50,560 --> 03:38:52,239 and we can 5165 03:38:52,239 --> 03:38:54,880 return we want to return the index so we 5166 03:38:54,880 --> 03:38:57,920 return I right that would be the index 5167 03:38:57,920 --> 03:38:59,279 of the bad 5168 03:38:59,279 --> 03:39:01,560 word otherwise if we don't find a bad 5169 03:39:01,560 --> 03:39:03,760 word we'll just keep going um in fact 5170 03:39:03,760 --> 03:39:04,720 we'll just keep going through all the 5171 03:39:04,720 --> 03:39:05,680 bad words and then we'll keep going 5172 03:39:05,680 --> 03:39:07,399 through all the rest of the 5173 03:39:07,399 --> 03:39:09,439 words and if we get to the end of 5174 03:39:09,439 --> 03:39:11,239 everything without finding any matches 5175 03:39:11,239 --> 03:39:13,279 then we can just return negative 5176 03:39:13,279 --> 03:39:16,760 1 makes sense right 5177 03:39:16,760 --> 03:39:18,760 cool let's run 5178 03:39:18,760 --> 03:39:23,199 that J declared not used right um so 5179 03:39:23,199 --> 03:39:24,880 we've come across this syntax before we 5180 03:39:24,880 --> 03:39:27,319 can ignore variables with an underscore 5181 03:39:27,319 --> 03:39:30,399 right let's run 5182 03:39:30,399 --> 03:39:33,000 that let's take a look at our test Suite 5183 03:39:33,000 --> 03:39:35,319 scanning message hey there John for bad 5184 03:39:35,319 --> 03:39:39,080 words index negative one that means none 5185 03:39:39,080 --> 03:39:42,040 were found right which makes sense we 5186 03:39:42,040 --> 03:39:44,720 didn't have any scanning message uh oh 5187 03:39:44,720 --> 03:39:47,479 my freck for bad words brick is a bad 5188 03:39:47,479 --> 03:39:50,040 word index 3 okay this is looking good 5189 03:39:50,040 --> 03:39:52,800 to me I'm going to go ahead and submit 5190 03:39:52,800 --> 03:39:55,279 that if you're familiar with object 5191 03:39:55,279 --> 03:39:57,720 literals in JavaScript or python 5192 03:39:57,720 --> 03:39:59,880 dictionaries then maps and go are 5193 03:39:59,880 --> 03:40:01,760 essentially the same thing maps are just 5194 03:40:01,760 --> 03:40:05,199 a way to associate a key with a value so 5195 03:40:05,199 --> 03:40:07,600 let's take a look at this example we 5196 03:40:07,600 --> 03:40:10,760 create a new map with this syntax here 5197 03:40:10,760 --> 03:40:12,800 we're going to use this built-in make 5198 03:40:12,800 --> 03:40:14,960 function and then pass in the type of 5199 03:40:14,960 --> 03:40:18,279 the map so map of string to integer so 5200 03:40:18,279 --> 03:40:21,520 we're mapping strings to integers and 5201 03:40:21,520 --> 03:40:23,479 we're going to say inside of the ages 5202 03:40:23,479 --> 03:40:27,239 map we're going to set the key John to 5203 03:40:27,239 --> 03:40:31,040 the integer 37 so again we're mapping 5204 03:40:31,040 --> 03:40:34,120 that name John to the value 37 rather 5205 03:40:34,120 --> 03:40:36,640 than creating an empty map and then kind 5206 03:40:36,640 --> 03:40:39,120 of adding key value pairs one at a time 5207 03:40:39,120 --> 03:40:41,439 we can also declare the entire map up 5208 03:40:41,439 --> 03:40:43,640 front and use kind of this colon syntax 5209 03:40:43,640 --> 03:40:45,800 to separate the keys and the values 5210 03:40:45,800 --> 03:40:49,000 and then we can also check how many keys 5211 03:40:49,000 --> 03:40:51,439 I guess keys and values are in the map 5212 03:40:51,439 --> 03:40:53,920 by using the built-in length function 5213 03:40:53,920 --> 03:40:55,600 similarly to how you would use it on a 5214 03:40:55,600 --> 03:40:58,359 slice um so in this case we create a new 5215 03:40:58,359 --> 03:41:00,840 map we create two keys each with their 5216 03:41:00,840 --> 03:41:02,640 Associated values and then by printing 5217 03:41:02,640 --> 03:41:04,160 the length we'll just print the number 5218 03:41:04,160 --> 03:41:06,000 two so let's jump right into the 5219 03:41:06,000 --> 03:41:08,080 assignment that's usually the best way 5220 03:41:08,080 --> 03:41:10,040 um to get an idea for how all the syntax 5221 03:41:10,040 --> 03:41:12,399 Works assignment says we can speed up 5222 03:41:12,399 --> 03:41:15,000 our contact info lookups by using a map 5223 03:41:15,000 --> 03:41:17,800 look up a value in a map by its key is 5224 03:41:17,800 --> 03:41:19,640 much faster than searching through a 5225 03:41:19,640 --> 03:41:22,359 slice so when we look up something in a 5226 03:41:22,359 --> 03:41:25,080 map by a given key that's going to be an 5227 03:41:25,080 --> 03:41:26,399 instant 5228 03:41:26,399 --> 03:41:29,000 lookup if we had stored it in a slice 5229 03:41:29,000 --> 03:41:30,520 then we'd have to search through the 5230 03:41:30,520 --> 03:41:32,840 entire slice sort of index by index 5231 03:41:32,840 --> 03:41:35,279 looking for the value that we want so 5232 03:41:35,279 --> 03:41:37,359 Maps can be a great way to make our code 5233 03:41:37,359 --> 03:41:38,359 more 5234 03:41:38,359 --> 03:41:40,399 efficient the assignment says complete 5235 03:41:40,399 --> 03:41:42,239 the get user map function it takes a 5236 03:41:42,239 --> 03:41:43,960 slice of names and a slice of phone 5237 03:41:43,960 --> 03:41:46,120 numbers and returns a map of of name to 5238 03:41:46,120 --> 03:41:49,080 user structs and potentially an error 5239 03:41:49,080 --> 03:41:53,040 okay so let me expand our coding window 5240 03:41:53,040 --> 03:41:55,199 here okay so we're returning a map of 5241 03:41:55,199 --> 03:41:56,840 string to user structs looks like the 5242 03:41:56,840 --> 03:41:59,600 user struct is defined right here if the 5243 03:41:59,600 --> 03:42:01,399 length of names and phone numbers is not 5244 03:42:01,399 --> 03:42:02,680 equal return error with the string 5245 03:42:02,680 --> 03:42:04,600 invalid sizes the first name in the name 5246 03:42:04,600 --> 03:42:07,439 slice matches the first number and so on 5247 03:42:07,439 --> 03:42:09,640 Okay cool so first things first we're 5248 03:42:09,640 --> 03:42:11,560 going to have to create a new map so 5249 03:42:11,560 --> 03:42:16,279 we'll do um user map 5250 03:42:16,279 --> 03:42:18,640 colon equals and I'm just going to 5251 03:42:18,640 --> 03:42:21,359 create a literal a new map literal 5252 03:42:21,359 --> 03:42:22,800 actually no I won't I'll do I'll use the 5253 03:42:22,800 --> 03:42:25,520 syntax from up here this works just fine 5254 03:42:25,520 --> 03:42:28,640 so we'll use the make function so make 5255 03:42:28,640 --> 03:42:31,640 map of string to 5256 03:42:31,640 --> 03:42:35,120 user right so that's now an empty 5257 03:42:35,120 --> 03:42:37,720 map and then what we're going to do is 5258 03:42:37,720 --> 03:42:38,880 check and make sure that these are the 5259 03:42:38,880 --> 03:42:42,800 same length so if the length of names 5260 03:42:42,800 --> 03:42:45,680 does not equal the length 5261 03:42:45,680 --> 03:42:48,239 of phone 5262 03:42:48,359 --> 03:42:52,040 numbers then we'll return nil so nil is 5263 03:42:52,040 --> 03:42:54,680 the zero value of a 5264 03:42:54,680 --> 03:42:57,760 map we could also return an empty map of 5265 03:42:57,760 --> 03:42:59,640 the same type but I'd say you should 5266 03:42:59,640 --> 03:43:02,199 prefer nil um for slices and maps and 5267 03:43:02,199 --> 03:43:04,279 things um and then the 5268 03:43:04,279 --> 03:43:06,920 error should say invalid sizes so 5269 03:43:06,920 --> 03:43:09,960 errors. new 5270 03:43:09,960 --> 03:43:12,000 invalid 5271 03:43:12,000 --> 03:43:16,760 sizes we'll import the errors package 5272 03:43:16,760 --> 03:43:18,800 Okay cool so if we get down to line 13 5273 03:43:18,800 --> 03:43:20,439 now we should know that both of these 5274 03:43:20,439 --> 03:43:22,760 slices names and phone numbers are of 5275 03:43:22,760 --> 03:43:25,640 the same size which means we can Loop um 5276 03:43:25,640 --> 03:43:29,199 like this so four I starting at zero and 5277 03:43:29,199 --> 03:43:31,479 I is less than the length of it doesn't 5278 03:43:31,479 --> 03:43:32,840 matter because they'll be the same right 5279 03:43:32,840 --> 03:43:34,080 length of 5280 03:43:34,080 --> 03:43:36,479 names 5281 03:43:36,479 --> 03:43:38,640 i++ then we can say 5282 03:43:38,640 --> 03:43:43,040 name is names at 5283 03:43:43,040 --> 03:43:47,199 I and we can say fun phone 5284 03:43:47,199 --> 03:43:50,040 number phone 5285 03:43:50,040 --> 03:43:52,760 numbers at 5286 03:43:52,760 --> 03:43:54,560 I 5287 03:43:54,560 --> 03:43:56,720 okay and then we're going to want to 5288 03:43:56,720 --> 03:43:58,760 insert values into the user map so we'll 5289 03:43:58,760 --> 03:44:04,000 do user map at the key in this case the 5290 03:44:04,000 --> 03:44:07,479 key is the name right so key is the name 5291 03:44:07,479 --> 03:44:09,640 and we'll set it equal to a new instance 5292 03:44:09,640 --> 03:44:13,239 of a user struct so 5293 03:44:13,359 --> 03:44:16,000 user and the user ruct has two Fields 5294 03:44:16,000 --> 03:44:18,880 name which will just again be the name 5295 03:44:18,880 --> 03:44:21,479 and the phone 5296 03:44:22,279 --> 03:44:24,680 number uh which will just be this phone 5297 03:44:24,680 --> 03:44:25,600 number 5298 03:44:25,600 --> 03:44:28,600 here 5299 03:44:28,920 --> 03:44:31,560 cool so that should fill the entire user 5300 03:44:31,560 --> 03:44:32,960 map with all of the names and phone 5301 03:44:32,960 --> 03:44:34,600 numbers and then by the end we should 5302 03:44:34,600 --> 03:44:36,000 just be able to 5303 03:44:36,000 --> 03:44:39,080 return user map 5304 03:44:39,080 --> 03:44:41,840 nil okay cool I think we got everything 5305 03:44:41,840 --> 03:44:45,640 let's go ahead and run that 5306 03:44:45,640 --> 03:44:48,479 and see what we get so creating map key 5307 03:44:48,479 --> 03:44:52,080 John value name number key Bob value 5308 03:44:52,080 --> 03:44:53,960 name number this is looking this is 5309 03:44:53,960 --> 03:44:55,199 looking correct to me here we have 5310 03:44:55,199 --> 03:44:57,000 creating map with invalid 5311 03:44:57,000 --> 03:45:00,319 sizes um if we take a look at the 5312 03:45:00,319 --> 03:45:02,640 tests uh yep that makes sense the second 5313 03:45:02,640 --> 03:45:04,880 test has two names but three numbers so 5314 03:45:04,880 --> 03:45:06,960 I would expect it to get that invalid 5315 03:45:06,960 --> 03:45:10,680 sizes error cool let's uh let's submit 5316 03:45:10,680 --> 03:45:13,600 that so the primary way you interact 5317 03:45:13,600 --> 03:45:15,600 with maps is just by setting and 5318 03:45:15,600 --> 03:45:18,120 deleting uh values at a given key right 5319 03:45:18,120 --> 03:45:20,399 they're very associative right a value 5320 03:45:20,399 --> 03:45:21,960 maps to a key but there's no other 5321 03:45:21,960 --> 03:45:24,120 ordering Maps aren't ordered from you 5322 03:45:24,120 --> 03:45:27,880 know index 0 1 2 3 uh like a slice is 5323 03:45:27,880 --> 03:45:29,560 everything's unordered you're literally 5324 03:45:29,560 --> 03:45:32,000 just mapping values to Keys Okay cool so 5325 03:45:32,000 --> 03:45:33,159 let's take a look at some of the 5326 03:45:33,159 --> 03:45:34,560 different syntax that we can use to 5327 03:45:34,560 --> 03:45:36,840 interact with maps so we can insert an 5328 03:45:36,840 --> 03:45:39,920 element by just setting the key equal to 5329 03:45:39,920 --> 03:45:43,080 the value um we can get an element out 5330 03:45:43,080 --> 03:45:45,840 just by accessing it directly at its key 5331 03:45:45,840 --> 03:45:47,640 we can delete Elements by using the 5332 03:45:47,640 --> 03:45:49,720 built-in delete function where we're 5333 03:45:49,720 --> 03:45:51,840 passing in the map itself and the key 5334 03:45:51,840 --> 03:45:53,520 that we want to delete notice that we're 5335 03:45:53,520 --> 03:45:55,040 not passing in the value at all we're 5336 03:45:55,040 --> 03:45:57,439 just passing in the key and then we can 5337 03:45:57,439 --> 03:46:02,080 also check if a key exists by parsing 5338 03:46:02,080 --> 03:46:04,600 the return value of kind of this access 5339 03:46:04,600 --> 03:46:07,279 syntax into two separate values where 5340 03:46:07,279 --> 03:46:09,279 the first value will be the element 5341 03:46:09,279 --> 03:46:13,000 itself and the second value is a Boolean 5342 03:46:13,000 --> 03:46:15,920 if the Boolean is true then the element 5343 03:46:15,920 --> 03:46:18,040 will be whatever element was stored of 5344 03:46:18,040 --> 03:46:22,040 that key however if the Boolean is false 5345 03:46:22,040 --> 03:46:23,560 that tells you that that key didn't 5346 03:46:23,560 --> 03:46:25,479 exist in the map and the element will 5347 03:46:25,479 --> 03:46:28,159 just be the zero value for its type 5348 03:46:28,159 --> 03:46:30,640 let's jump into the assignment so it 5349 03:46:30,640 --> 03:46:33,040 says in fact let me uh let me resize 5350 03:46:33,040 --> 03:46:33,960 this a 5351 03:46:33,960 --> 03:46:36,319 bit says it's important to keep up with 5352 03:46:36,319 --> 03:46:37,760 privacy regulations and to respect our 5353 03:46:37,760 --> 03:46:39,560 users data we need a function that will 5354 03:46:39,560 --> 03:46:42,080 delete user records okay complete the 5355 03:46:42,080 --> 03:46:44,640 delete if necessary function um it takes 5356 03:46:44,640 --> 03:46:47,800 a a map of users and a name which I'm 5357 03:46:47,800 --> 03:46:51,000 going to guess is the key in the map and 5358 03:46:51,000 --> 03:46:53,239 it will return a Boolean saying whether 5359 03:46:53,239 --> 03:46:56,080 or not the user was deleted and then an 5360 03:46:56,080 --> 03:46:58,399 error if something went wrong okay cool 5361 03:46:58,399 --> 03:47:00,120 so if the user does not exist in the map 5362 03:47:00,120 --> 03:47:01,840 return the error not found oh 5363 03:47:01,840 --> 03:47:03,080 interesting so if we're trying to delete 5364 03:47:03,080 --> 03:47:04,720 something and it's not there um that's 5365 03:47:04,720 --> 03:47:07,560 an error if they exist but aren't 5366 03:47:07,560 --> 03:47:10,479 scheduled for deletion then return 5367 03:47:10,479 --> 03:47:13,120 deleted as false so we this will be 5368 03:47:13,120 --> 03:47:15,040 false um and there won't be any errors 5369 03:47:15,040 --> 03:47:17,040 um but if they exist and are scheduled 5370 03:47:17,040 --> 03:47:19,760 for deletion then we'll return uh the 5371 03:47:19,760 --> 03:47:22,279 deleted Boolean as true with no other 5372 03:47:22,279 --> 03:47:25,080 errors okay that's making sense to me 5373 03:47:25,080 --> 03:47:27,560 and then a note on how maps are passed 5374 03:47:27,560 --> 03:47:30,520 into functions is that like slices maps 5375 03:47:30,520 --> 03:47:32,680 are actually passed by reference so even 5376 03:47:32,680 --> 03:47:35,199 though this function delete if necessary 5377 03:47:35,199 --> 03:47:39,479 does not return a map if we mutate this 5378 03:47:39,479 --> 03:47:42,040 users map it will be mutated for the 5379 03:47:42,040 --> 03:47:43,399 color of the function so that's how 5380 03:47:43,399 --> 03:47:45,319 we're able to delete something from the 5381 03:47:45,319 --> 03:47:47,040 map even though we're not returning the 5382 03:47:47,040 --> 03:47:49,120 map once we're done with it so the first 5383 03:47:49,120 --> 03:47:50,720 thing we need to do is just check and 5384 03:47:50,720 --> 03:47:52,319 see if the name that we're trying to 5385 03:47:52,319 --> 03:47:57,279 delete exists so let's do this if blank 5386 03:47:57,279 --> 03:48:00,399 okay colon equals 5387 03:48:00,399 --> 03:48:02,760 users at 5388 03:48:02,760 --> 03:48:07,880 name not not okay so uh this is that 5389 03:48:07,880 --> 03:48:10,720 kind of special if statement syntax 5390 03:48:10,720 --> 03:48:13,399 right um where we're uh actually 5391 03:48:13,399 --> 03:48:16,159 ignoring the value at self um we're just 5392 03:48:16,159 --> 03:48:18,120 interested in that Boolean value telling 5393 03:48:18,120 --> 03:48:21,680 us whether or not this um this key 5394 03:48:21,680 --> 03:48:23,840 exists in the map and if it does not 5395 03:48:23,840 --> 03:48:26,120 then we're going to go ahead and return 5396 03:48:26,120 --> 03:48:28,199 uh return the error not found so false 5397 03:48:28,199 --> 03:48:29,640 because we always do zero values for 5398 03:48:29,640 --> 03:48:30,880 everything besides the error and then 5399 03:48:30,880 --> 03:48:33,040 errors. 5400 03:48:33,040 --> 03:48:36,159 new not found and we'll make sure to 5401 03:48:36,159 --> 03:48:38,319 import that errors 5402 03:48:38,319 --> 03:48:40,920 package okay cool and again I'm just I'm 5403 03:48:40,920 --> 03:48:43,840 just uh using this syntax here to check 5404 03:48:43,840 --> 03:48:45,760 if a key exists 5405 03:48:45,760 --> 03:48:47,960 cool moving on okay so if we get past uh 5406 03:48:47,960 --> 03:48:49,920 past that guard Clause to line 12 then 5407 03:48:49,920 --> 03:48:54,159 we know um that the user exists so um at 5408 03:48:54,159 --> 03:48:55,840 this point ah we need to check if 5409 03:48:55,840 --> 03:48:57,359 they're scheduled for deletion so I'm 5410 03:48:57,359 --> 03:48:58,600 actually going to switch up my syntax 5411 03:48:58,600 --> 03:49:01,239 here the user struct has the scheduled 5412 03:49:01,239 --> 03:49:03,239 for deletion Boolean so I'm going to go 5413 03:49:03,239 --> 03:49:06,279 ahead and do this on a separate 5414 03:49:06,279 --> 03:49:10,120 line and I will save that user so I'll 5415 03:49:10,120 --> 03:49:15,720 do um existing user 5416 03:49:16,840 --> 03:49:18,760 and then we'll just do if not 5417 03:49:18,760 --> 03:49:21,520 okay so that down here now I can use 5418 03:49:21,520 --> 03:49:23,399 that existing user struct so I can say 5419 03:49:23,399 --> 03:49:28,479 if existing user. scheduled for 5420 03:49:28,479 --> 03:49:30,520 deletion so if they exist and are 5421 03:49:30,520 --> 03:49:32,239 schedul for deletion return deleted as 5422 03:49:32,239 --> 03:49:33,279 true with no errors and delete the 5423 03:49:33,279 --> 03:49:34,560 record from the map so we need to use 5424 03:49:34,560 --> 03:49:38,920 this built-in delete function so we'll 5425 03:49:38,960 --> 03:49:40,479 delete 5426 03:49:40,479 --> 03:49:45,920 users name and then we'll return true 5427 03:49:45,920 --> 03:49:48,000 n all right so if they are scheduled for 5428 03:49:48,000 --> 03:49:50,359 deletion we'll delete them and report 5429 03:49:50,359 --> 03:49:54,319 back that we deleted them cool um 5430 03:49:54,319 --> 03:49:57,800 otherwise if they're not scheduled for 5431 03:49:57,800 --> 03:49:59,880 deletion return deleted as false with no 5432 03:49:59,880 --> 03:50:01,040 errors so 5433 03:50:01,040 --> 03:50:03,359 return false 5434 03:50:03,359 --> 03:50:05,800 no okay that looks right to me let's go 5435 03:50:05,800 --> 03:50:08,439 ahead and run 5436 03:50:09,279 --> 03:50:11,960 that attempting to delete John deleted 5437 03:50:11,960 --> 03:50:14,960 JN attempting to delete musk not found 5438 03:50:14,960 --> 03:50:16,720 Santa not found attempt to delete Kade 5439 03:50:16,720 --> 03:50:18,159 did not delete Kade Okay cool so I mean 5440 03:50:18,159 --> 03:50:19,520 all that look it looks like all the 5441 03:50:19,520 --> 03:50:21,439 cases were covered let's just come down 5442 03:50:21,439 --> 03:50:22,600 here and take a 5443 03:50:22,600 --> 03:50:25,800 look okay so we had a John and JN was 5444 03:50:25,800 --> 03:50:27,880 deleted and then attempting to delete 5445 03:50:27,880 --> 03:50:30,040 musk there's not actually a musk in the 5446 03:50:30,040 --> 03:50:32,600 map so not found makes sense um there's 5447 03:50:32,600 --> 03:50:36,159 also not a Santa and Cade was not 5448 03:50:36,159 --> 03:50:38,720 scheduled for deletion so he did not get 5449 03:50:38,720 --> 03:50:41,520 deleted and then the final map still has 5450 03:50:41,520 --> 03:50:44,520 those keys that looks correct to me in 5451 03:50:44,520 --> 03:50:46,159 the this next section we're going to be 5452 03:50:46,159 --> 03:50:48,399 covering some of the material from the 5453 03:50:48,399 --> 03:50:51,000 go blog now I'm not going to read all of 5454 03:50:51,000 --> 03:50:53,760 this out uh that would be a little dry 5455 03:50:53,760 --> 03:50:56,040 but I definitely recommend reading this 5456 03:50:56,040 --> 03:50:58,040 over if you have the time otherwise I'm 5457 03:50:58,040 --> 03:51:00,520 going to cover kind of the key points so 5458 03:51:00,520 --> 03:51:02,680 the first question is what makes a type 5459 03:51:02,680 --> 03:51:05,319 qualify to be able to be used as a map 5460 03:51:05,319 --> 03:51:08,279 key okay so any type can be used as a 5461 03:51:08,279 --> 03:51:10,800 map value but not every type can be used 5462 03:51:10,800 --> 03:51:14,359 as a map key and that's because map Keys 5463 03:51:14,359 --> 03:51:16,080 make may be of any type that is 5464 03:51:16,080 --> 03:51:18,760 comparable so things like strings 5465 03:51:18,760 --> 03:51:21,520 booleans um numbers all those can be 5466 03:51:21,520 --> 03:51:24,399 compared for a quality what cannot be 5467 03:51:24,399 --> 03:51:28,159 compared for equality are slices maps 5468 03:51:28,159 --> 03:51:30,279 and functions and kind of one of the 5469 03:51:30,279 --> 03:51:32,439 reasons for that is slices and maps and 5470 03:51:32,439 --> 03:51:34,359 functions they're kind of just pointers 5471 03:51:34,359 --> 03:51:37,880 to addresses in memory so if you compare 5472 03:51:37,880 --> 03:51:40,199 one slice to another slice you're not 5473 03:51:40,199 --> 03:51:42,640 really comparing the underlying values 5474 03:51:42,640 --> 03:51:45,000 you're actually comparing kind of where 5475 03:51:45,000 --> 03:51:47,600 those two slices are stored in your 5476 03:51:47,600 --> 03:51:49,000 computer's 5477 03:51:49,000 --> 03:51:51,159 RAM and because they're stored in 5478 03:51:51,159 --> 03:51:53,479 different places you'll actually get two 5479 03:51:53,479 --> 03:51:55,560 slices with maybe the exact same values 5480 03:51:55,560 --> 03:51:57,880 stored in them say slice one has the 5481 03:51:57,880 --> 03:51:59,960 numbers one two three in the first three 5482 03:51:59,960 --> 03:52:01,920 indexes and the second slice has the 5483 03:52:01,920 --> 03:52:04,880 same they might still be compared as 5484 03:52:04,880 --> 03:52:06,840 unequal because they're stored in 5485 03:52:06,840 --> 03:52:09,880 different addresses in memory so I mean 5486 03:52:09,880 --> 03:52:12,159 all that being said long story short you 5487 03:52:12,159 --> 03:52:15,040 just can't use slices and maps maps and 5488 03:52:15,040 --> 03:52:18,279 functions as map keys so to answer the 5489 03:52:18,279 --> 03:52:19,560 question what makes type qualifi to be 5490 03:52:19,560 --> 03:52:23,399 used as a map key the type is comparable 5491 03:52:23,399 --> 03:52:25,479 this next question is interesting and 5492 03:52:25,479 --> 03:52:28,120 kind of plays on the idea that we can 5493 03:52:28,120 --> 03:52:30,600 Nest Maps um kind of one inside the 5494 03:52:30,600 --> 03:52:32,120 other or we could do something that's 5495 03:52:32,120 --> 03:52:33,880 arguably simpler let me show you what I 5496 03:52:33,880 --> 03:52:38,560 mean so here is an example of a map of 5497 03:52:38,560 --> 03:52:43,279 strings that maps to another map which 5498 03:52:43,279 --> 03:52:46,359 maps from strings to integers so like 5499 03:52:46,359 --> 03:52:47,880 the first string kind of maps to the 5500 03:52:47,880 --> 03:52:49,720 second string which maps to an integer 5501 03:52:49,720 --> 03:52:51,399 if you want to think about it that way 5502 03:52:51,399 --> 03:52:53,319 if you're familiar with Json objects 5503 03:52:53,319 --> 03:52:55,760 this would be like mapping Json objects 5504 03:52:55,760 --> 03:52:59,120 kind of down multiple uh levels of keys 5505 03:52:59,120 --> 03:53:02,040 so in the example given in the go blog 5506 03:53:02,040 --> 03:53:03,399 essentially what's being said is we're 5507 03:53:03,399 --> 03:53:07,439 mapping um two strings to a count and so 5508 03:53:07,439 --> 03:53:09,319 what that looks like in code is if we 5509 03:53:09,319 --> 03:53:11,040 want to get access to the count we 5510 03:53:11,040 --> 03:53:14,520 actually have to go to the map index the 5511 03:53:14,520 --> 03:53:17,800 nested map with a key and then index 5512 03:53:17,800 --> 03:53:20,239 into that next map with another key 5513 03:53:20,239 --> 03:53:22,040 before we get the value out now this 5514 03:53:22,040 --> 03:53:24,640 looks simple on the surface but what 5515 03:53:24,640 --> 03:53:26,640 actually happens is when you need when 5516 03:53:26,640 --> 03:53:29,040 you go down those nested levels you 5517 03:53:29,040 --> 03:53:31,319 actually can't be sure that the inner 5518 03:53:31,319 --> 03:53:34,920 map exists and So to avoid panicking 5519 03:53:34,920 --> 03:53:36,880 your code will actually Panic by the way 5520 03:53:36,880 --> 03:53:39,560 if you try to access a key in a map that 5521 03:53:39,560 --> 03:53:42,439 is nil So to avoid panicking you have to 5522 03:53:42,439 --> 03:53:44,120 check and make sure that those nested 5523 03:53:44,120 --> 03:53:47,399 Maps actually exist which just results 5524 03:53:47,399 --> 03:53:50,640 in a lot of extra code so while nesting 5525 03:53:50,640 --> 03:53:52,760 Maps definitely works and I've used it 5526 03:53:52,760 --> 03:53:55,279 quite a bit there can in some instances 5527 03:53:55,279 --> 03:53:57,359 be a simpler way which is to actually 5528 03:53:57,359 --> 03:54:01,279 use a struct as a key notice that a 5529 03:54:01,279 --> 03:54:03,880 struct was not named as one of the 5530 03:54:03,880 --> 03:54:06,359 non-comparable types structs are 5531 03:54:06,359 --> 03:54:09,479 comparable so if you want to create a 5532 03:54:09,479 --> 03:54:11,760 map that kind of has multiple keys that 5533 03:54:11,760 --> 03:54:13,880 kind of combine together to form a 5534 03:54:13,880 --> 03:54:16,880 composite key then just create a new 5535 03:54:16,880 --> 03:54:19,600 struct right with two values inside of 5536 03:54:19,600 --> 03:54:22,520 it and those two values kind of unique 5537 03:54:22,520 --> 03:54:25,520 together create their own key so this 5538 03:54:25,520 --> 03:54:27,159 simplifies a lot of things where now we 5539 03:54:27,159 --> 03:54:29,600 can have one map and we can use that 5540 03:54:29,600 --> 03:54:32,199 struct key to create kind of uniqueness 5541 03:54:32,199 --> 03:54:33,920 across two different values this might 5542 03:54:33,920 --> 03:54:35,279 be useful for example if you're trying 5543 03:54:35,279 --> 03:54:38,640 to create a map That's Unique for first 5544 03:54:38,640 --> 03:54:40,680 last name combinations right you want 5545 03:54:40,680 --> 03:54:42,439 Lane Wagner stored in two different 5546 03:54:42,439 --> 03:54:44,640 fields first name and last name to be 5547 03:54:44,640 --> 03:54:47,159 unique together so to answer the 5548 03:54:47,159 --> 03:54:49,080 question which is simpler to use a 5549 03:54:49,080 --> 03:54:52,080 struct directly as a key or to Nest maps 5550 03:54:52,080 --> 03:54:54,560 and um the authors of the go blog and I 5551 03:54:54,560 --> 03:54:57,680 would agree argue that using a struct 5552 03:54:57,680 --> 03:54:59,640 directly is going to be simpler let's 5553 03:54:59,640 --> 03:55:01,520 jump right into this next assignment 5554 03:55:01,520 --> 03:55:04,120 says we have a slice of user IDs okay so 5555 03:55:04,120 --> 03:55:06,199 those are strings and each instance of 5556 03:55:06,199 --> 03:55:07,960 an ID in the slice indicates that a 5557 03:55:07,960 --> 03:55:10,080 message was sent to that user we need to 5558 03:55:10,080 --> 03:55:12,680 count up how many times each user's ID 5559 03:55:12,680 --> 03:55:14,439 appears in the slice to track how how 5560 03:55:14,439 --> 03:55:16,840 many messages they received implement 5561 03:55:16,840 --> 03:55:19,120 the get counts function okay so that's 5562 03:55:19,120 --> 03:55:20,920 this one it should return a map of 5563 03:55:20,920 --> 03:55:23,120 string to int so that each int is a 5564 03:55:23,120 --> 03:55:24,600 count of how many times each string was 5565 03:55:24,600 --> 03:55:26,800 found in the slice okay cool simple 5566 03:55:26,800 --> 03:55:29,920 enough so let's create a new map so this 5567 03:55:29,920 --> 03:55:33,000 will be the counts map and it's going to 5568 03:55:33,000 --> 03:55:37,040 be a map of string to 5569 03:55:37,479 --> 03:55:40,359 integer and then let's Loop over all of 5570 03:55:40,359 --> 03:55:46,080 the user IDs so four blank user ID 5571 03:55:46,080 --> 03:55:48,439 in range user 5572 03:55:48,439 --> 03:55:50,680 IDs we're just we're going to ignore the 5573 03:55:50,680 --> 03:55:53,040 index because we don't care about 5574 03:55:53,040 --> 03:55:55,439 it and the first thing we're going to do 5575 03:55:55,439 --> 03:55:59,600 is check to see if um a value in the map 5576 03:55:59,600 --> 03:56:02,880 for the given user ID already exists so 5577 03:56:02,880 --> 03:56:05,520 count okay colon 5578 03:56:05,520 --> 03:56:08,760 equals user 5579 03:56:08,760 --> 03:56:12,080 IDs sorry 5580 03:56:12,080 --> 03:56:16,239 counts at user ID 5581 03:56:17,199 --> 03:56:21,600 right cool um in fact now like now that 5582 03:56:21,600 --> 03:56:22,880 I type that out I'm not actually sure 5583 03:56:22,880 --> 03:56:26,399 that I need this because if I don't use 5584 03:56:26,399 --> 03:56:29,080 this this access will still work it's 5585 03:56:29,080 --> 03:56:31,239 just if if the key didn't exist count 5586 03:56:31,239 --> 03:56:33,920 will be zero which is fine so actually I 5587 03:56:33,920 --> 03:56:37,560 I don't even think I care um cool so we 5588 03:56:37,560 --> 03:56:39,520 get the count it'll be zero if it didn't 5589 03:56:39,520 --> 03:56:41,120 yet exist and then we just increment it 5590 03:56:41,120 --> 03:56:44,600 by one so count Plus+ 5591 03:56:44,600 --> 03:56:46,239 and then we'll save it back into the map 5592 03:56:46,239 --> 03:56:50,000 so counts at user ID equals count so 5593 03:56:50,000 --> 03:56:51,680 we're just grabbing it out incrementing 5594 03:56:51,680 --> 03:56:55,560 it by one and putting it back that seems 5595 03:56:55,560 --> 03:56:57,600 like what we want to do right and then 5596 03:56:57,600 --> 03:57:00,720 at the end we'll just return 5597 03:57:00,720 --> 03:57:02,239 counts 5598 03:57:02,239 --> 03:57:04,199 cool let's go ahead and run that and see 5599 03:57:04,199 --> 03:57:06,479 what we 5600 03:57:07,920 --> 03:57:11,279 get Jing counts for 10,000 user IDs 5601 03:57:11,279 --> 03:57:14,439 Counts from selected IDs 0 0 has 31 f F 5602 03:57:14,439 --> 03:57:19,239 has 27 DD has 37 okay and if I look down 5603 03:57:19,239 --> 03:57:22,359 here it looks like the IDS are being 5604 03:57:22,359 --> 03:57:23,920 generated 5605 03:57:23,920 --> 03:57:28,040 randomly cool so let's go ahead and 5606 03:57:28,040 --> 03:57:32,000 submit it because this feels 5607 03:57:32,520 --> 03:57:35,439 right cool we're good to go this next 5608 03:57:35,439 --> 03:57:39,159 section is about a piece or an excerpt 5609 03:57:39,159 --> 03:57:42,239 from the effective go book um that is a 5610 03:57:42,239 --> 03:57:44,239 book that i' highly recommend reading um 5611 03:57:44,239 --> 03:57:45,680 some of the stuff's a bit outdated 5612 03:57:45,680 --> 03:57:47,080 they've made the decision not to 5613 03:57:47,080 --> 03:57:49,640 continuously update effective go but it 5614 03:57:49,640 --> 03:57:52,000 is an open-source book you can go read 5615 03:57:52,000 --> 03:57:53,880 the whole thing for free um and the link 5616 03:57:53,880 --> 03:57:55,640 is right there so go check that out if 5617 03:57:55,640 --> 03:57:57,720 you're interested um that said you don't 5618 03:57:57,720 --> 03:57:59,560 need to I'll be talking through um the 5619 03:57:59,560 --> 03:58:01,800 parts that we care about here so Maps 5620 03:58:01,800 --> 03:58:04,640 can have at most blank values associated 5621 03:58:04,640 --> 03:58:06,399 with the same key the answers are one 5622 03:58:06,399 --> 03:58:09,159 any number of three and two well maps 5623 03:58:09,159 --> 03:58:11,479 are associative right they map a single 5624 03:58:11,479 --> 03:58:14,120 key to a single value and you can't have 5625 03:58:14,120 --> 03:58:16,720 duplicates of the same key in a map that 5626 03:58:16,720 --> 03:58:18,080 wouldn't make any sense right then when 5627 03:58:18,080 --> 03:58:19,680 you put in a key you would maybe get 5628 03:58:19,680 --> 03:58:21,239 back a slice like that doesn't quite 5629 03:58:21,239 --> 03:58:23,720 work so the answer is Maps can have at 5630 03:58:23,720 --> 03:58:26,359 most one value associated with the same 5631 03:58:26,359 --> 03:58:28,359 key the next question says attempting to 5632 03:58:28,359 --> 03:58:29,840 get a value from a map where the key 5633 03:58:29,840 --> 03:58:32,159 does not exist Returns the closest Value 5634 03:58:32,159 --> 03:58:35,000 panics or Returns the zero value um 5635 03:58:35,000 --> 03:58:36,520 that's covered here in the section on 5636 03:58:36,520 --> 03:58:39,439 missing keys but basically to summarize 5637 03:58:39,439 --> 03:58:41,800 if you attempt to get a I mean we 5638 03:58:41,800 --> 03:58:43,359 actually covered this in the last um the 5639 03:58:43,359 --> 03:58:44,960 last coding assignment but if you 5640 03:58:44,960 --> 03:58:48,199 attempt to access a key in a map where 5641 03:58:48,199 --> 03:58:49,720 the key doesn't exist you'll just get 5642 03:58:49,720 --> 03:58:52,000 back the zero value so for example if 5643 03:58:52,000 --> 03:58:55,960 it's a map of strings to integers and 5644 03:58:55,960 --> 03:58:58,560 you access a string that doesn't exist 5645 03:58:58,560 --> 03:59:01,720 you'll get back as the value zero and 5646 03:59:01,720 --> 03:59:03,399 that's kind of nice just because 5647 03:59:03,399 --> 03:59:06,040 accessing values in a map is a safe 5648 03:59:06,040 --> 03:59:08,520 operation your code will not will not 5649 03:59:08,520 --> 03:59:10,560 panic so to answer the question it 5650 03:59:10,560 --> 03:59:13,159 Returns the zero value and it's also 5651 03:59:13,159 --> 03:59:15,279 worth pointing out really quickly that 5652 03:59:15,279 --> 03:59:18,520 if the map doesn't exist so not that the 5653 03:59:18,520 --> 03:59:20,120 key that you're trying to access doesn't 5654 03:59:20,120 --> 03:59:21,840 exist but if the map itself doesn't 5655 03:59:21,840 --> 03:59:24,520 exist if it's a nil map then your code 5656 03:59:24,520 --> 03:59:26,279 will Panic so that is a dangerous 5657 03:59:26,279 --> 03:59:27,680 operation you want to make sure you're 5658 03:59:27,680 --> 03:59:29,960 always accessing values in maps that 5659 03:59:29,960 --> 03:59:32,399 have been initialized the next question 5660 03:59:32,399 --> 03:59:34,319 is a function can mutate the values 5661 03:59:34,319 --> 03:59:37,319 stored in a map and those changes blank 5662 03:59:37,319 --> 03:59:40,640 the colar affect or do not affect the 5663 03:59:40,640 --> 03:59:43,640 collar now the answer to this one is in 5664 03:59:43,640 --> 03:59:46,479 this first section that Maps like slices 5665 03:59:46,479 --> 03:59:48,960 are references so when we pass a map 5666 03:59:48,960 --> 03:59:52,239 into a function that function can change 5667 03:59:52,239 --> 03:59:54,560 what's in the map and those changes will 5668 03:59:54,560 --> 03:59:56,720 be visible outside of the function this 5669 03:59:56,720 --> 03:59:58,120 is different from Primitives right 5670 03:59:58,120 --> 04:00:01,040 strings integers um booleans those are 5671 04:00:01,040 --> 04:00:02,920 all passed into functions by value if 5672 04:00:02,920 --> 04:00:05,040 you mutate them within a function uh the 5673 04:00:05,040 --> 04:00:06,520 the the CER of that function will not 5674 04:00:06,520 --> 04:00:08,720 see those changes unless you return 5675 04:00:08,720 --> 04:00:11,279 those values but the same does not hold 5676 04:00:11,279 --> 04:00:14,720 true for slices and maps so to answer 5677 04:00:14,720 --> 04:00:16,720 the question uh a function can mutate 5678 04:00:16,720 --> 04:00:18,720 the values uh stored in a map and those 5679 04:00:18,720 --> 04:00:22,120 changes they do affect the CER the next 5680 04:00:22,120 --> 04:00:23,920 question says what does the second 5681 04:00:23,920 --> 04:00:26,199 return value from a retrieve operation 5682 04:00:26,199 --> 04:00:29,840 in a map indicate so let's take a look 5683 04:00:29,840 --> 04:00:32,000 at this code example here so we've got 5684 04:00:32,000 --> 04:00:34,479 this time zone map where we're accessing 5685 04:00:34,479 --> 04:00:37,720 the map at a given a given key and it 5686 04:00:37,720 --> 04:00:42,159 can return two values the first value is 5687 04:00:42,159 --> 04:00:43,560 the value associated with the key and 5688 04:00:43,560 --> 04:00:46,000 the second value is a Boolean right we 5689 04:00:46,000 --> 04:00:47,439 used this in the last coding assignment 5690 04:00:47,439 --> 04:00:49,080 so a Boolean that indicates whether the 5691 04:00:49,080 --> 04:00:51,239 value at the key is a nil value nope 5692 04:00:51,239 --> 04:00:52,880 that's not accurate a Boolean that 5693 04:00:52,880 --> 04:00:55,040 indicates whether the key exists that's 5694 04:00:55,040 --> 04:00:56,080 the 5695 04:00:56,080 --> 04:00:59,960 one let's practice with some nested Maps 5696 04:00:59,960 --> 04:01:02,279 so like we talked about earlier Maps can 5697 04:01:02,279 --> 04:01:05,199 contain other Maps as their values not 5698 04:01:05,199 --> 04:01:07,319 as not as their keys right so let's jump 5699 04:01:07,319 --> 04:01:09,600 into the assignment says because texo is 5700 04:01:09,600 --> 04:01:11,319 a glorified customer database right I 5701 04:01:11,319 --> 04:01:13,960 mean we're sending sms and email 5702 04:01:13,960 --> 04:01:15,880 messages to a giant list of customers or 5703 04:01:15,880 --> 04:01:17,960 basically just a big customer database 5704 04:01:17,960 --> 04:01:19,560 um we have a lot of internal Logic for 5705 04:01:19,560 --> 04:01:21,880 sorting and dealing with customer names 5706 04:01:21,880 --> 04:01:23,960 complete the get name counts function it 5707 04:01:23,960 --> 04:01:26,279 takes a slice of strings 5708 04:01:26,279 --> 04:01:29,000 names and returns a nested map this is 5709 04:01:29,000 --> 04:01:30,199 going to be very similar to the last 5710 04:01:30,199 --> 04:01:33,000 assignment we did um but this time it's 5711 04:01:33,000 --> 04:01:34,560 going to be a nested map where the first 5712 04:01:34,560 --> 04:01:36,279 key is all the unique First characters 5713 04:01:36,279 --> 04:01:38,560 of the names and the second key is all 5714 04:01:38,560 --> 04:01:40,560 of the names themselves so this could be 5715 04:01:40,560 --> 04:01:42,279 useful if for some reason we wanted to 5716 04:01:42,279 --> 04:01:44,279 get access to all of the names that 5717 04:01:44,279 --> 04:01:47,040 start with a very quickly so to kind of 5718 04:01:47,040 --> 04:01:49,120 visualize this we've got this example if 5719 04:01:49,120 --> 04:01:52,399 the input names slice is this slice here 5720 04:01:52,399 --> 04:01:54,560 Billy Billy Bob Joe it would create the 5721 04:01:54,560 --> 04:01:57,600 following nested map so the first key is 5722 04:01:57,600 --> 04:01:59,239 just a 5723 04:01:59,239 --> 04:02:03,199 letter the second key is the full name 5724 04:02:03,199 --> 04:02:06,840 and then the value is um the number of 5725 04:02:06,840 --> 04:02:08,600 times that name showed up in the 5726 04:02:08,600 --> 04:02:10,600 original list and then it's worth 5727 04:02:10,600 --> 04:02:13,040 pointing out here that the return value 5728 04:02:13,040 --> 04:02:16,760 is a map of runes to a map of strings 5729 04:02:16,760 --> 04:02:19,199 and integers in go we often just 5730 04:02:19,199 --> 04:02:22,640 represent individual characters as runes 5731 04:02:22,640 --> 04:02:24,880 rather than strings of length one it 5732 04:02:24,880 --> 04:02:26,960 just gives us a little more um kind of 5733 04:02:26,960 --> 04:02:29,319 assurity in our type system okay so 5734 04:02:29,319 --> 04:02:32,720 let's start by creating a new top level 5735 04:02:32,720 --> 04:02:35,279 map so we'll call it counts and we'll 5736 04:02:35,279 --> 04:02:39,199 make that full map now it's important to 5737 04:02:39,199 --> 04:02:42,399 understand because this map contains 5738 04:02:42,399 --> 04:02:44,439 Maps inside of it we we will need to 5739 04:02:44,439 --> 04:02:46,640 continuously initialize new maps I'll 5740 04:02:46,640 --> 04:02:49,439 show you what that looks like so now 5741 04:02:49,439 --> 04:02:51,000 let's just uh loop over all these names 5742 04:02:51,000 --> 04:02:51,760 so 5743 04:02:51,760 --> 04:02:54,840 for um we don't care about the index 5744 04:02:54,840 --> 04:02:57,680 name and range 5745 04:02:57,680 --> 04:03:00,680 names Okay so we've got a name the first 5746 04:03:00,680 --> 04:03:03,239 thing we need to do is actually check 5747 04:03:03,239 --> 04:03:06,279 and see if we already have a map 5748 04:03:06,279 --> 04:03:07,920 associated with the first character of 5749 04:03:07,920 --> 04:03:10,399 this name so let's get that first 5750 04:03:10,399 --> 04:03:14,359 character let's do um if we probably 5751 04:03:14,359 --> 04:03:16,159 need to do some safety checking so like 5752 04:03:16,159 --> 04:03:18,800 if length of 5753 04:03:18,800 --> 04:03:20,920 name actually the easiest thing to do 5754 04:03:20,920 --> 04:03:24,319 would just be if name is the empty 5755 04:03:24,319 --> 04:03:26,720 string then we'll 5756 04:03:26,720 --> 04:03:29,279 continue we don't care about blank names 5757 04:03:29,279 --> 04:03:30,800 they they don't do anything for us right 5758 04:03:30,800 --> 04:03:33,520 so we'll just we'll just skip them great 5759 04:03:33,520 --> 04:03:36,199 if it's not the empty string then we can 5760 04:03:36,199 --> 04:03:41,840 say first character is name zero okay so 5761 04:03:41,840 --> 04:03:44,399 that gives us the Rune at 5762 04:03:44,399 --> 04:03:47,199 um the first index in the 5763 04:03:47,199 --> 04:03:50,359 name and then what we can do is look up 5764 04:03:50,359 --> 04:03:54,359 in our map so counts at first oops 5765 04:03:54,359 --> 04:03:56,720 counts at first 5766 04:03:56,720 --> 04:04:01,560 character um we can see if the inner 5767 04:04:01,560 --> 04:04:03,479 map 5768 04:04:03,479 --> 04:04:07,439 exists so if it does not exist not if 5769 04:04:07,439 --> 04:04:09,720 not 5770 04:04:09,720 --> 04:04:11,920 okay let's just keep it simple if it 5771 04:04:11,920 --> 04:04:14,279 doesn't exist we'll just initialize it 5772 04:04:14,279 --> 04:04:16,399 so if it does not exist we'll say counts 5773 04:04:16,399 --> 04:04:17,520 at first 5774 04:04:17,520 --> 04:04:20,080 character equals and we'll initialize 5775 04:04:20,080 --> 04:04:23,479 the new inner map so we just need a new 5776 04:04:23,479 --> 04:04:26,279 map of string to 5777 04:04:26,279 --> 04:04:30,920 integer at that first character key 5778 04:04:30,920 --> 04:04:34,960 right right in fact to be explicit I'm 5779 04:04:34,960 --> 04:04:37,560 going to ignore the inner map 5780 04:04:37,560 --> 04:04:41,040 there so by the time we get down here to 5781 04:04:41,040 --> 04:04:44,399 line 18 we should be 100% certain that 5782 04:04:44,399 --> 04:04:47,239 counts at first character contains an 5783 04:04:47,239 --> 04:04:49,920 initialized map so then we can just 5784 04:04:49,920 --> 04:04:53,080 simply do counts at first character 5785 04:04:53,080 --> 04:04:56,080 at 5786 04:04:57,880 --> 04:04:59,920 name 5787 04:04:59,920 --> 04:05:01,600 Plus+ 5788 04:05:01,600 --> 04:05:04,000 right because we've we've made sure that 5789 04:05:04,000 --> 04:05:09,399 the inner map exists and if the name key 5790 04:05:09,399 --> 04:05:11,840 doesn't exist it will return a zero 5791 04:05:11,840 --> 04:05:14,279 which we could then increment and save 5792 04:05:14,279 --> 04:05:16,960 back into the map so that should work 5793 04:05:16,960 --> 04:05:17,840 just 5794 04:05:17,840 --> 04:05:21,520 fine at the end we can return 5795 04:05:21,520 --> 04:05:25,319 counts cool hopefully that makes 5796 04:05:25,319 --> 04:05:28,760 sense and we've got some test cases down 5797 04:05:28,760 --> 04:05:31,520 here Matthew George Drew Philip Bryant 5798 04:05:31,520 --> 04:05:33,159 and then a big list okay cool let's run 5799 04:05:33,159 --> 04:05:35,159 it and see what 5800 04:05:35,159 --> 04:05:38,960 happens whoops cannot use first Char 5801 04:05:38,960 --> 04:05:41,560 variable of type bite as Rune 5802 04:05:41,560 --> 04:05:45,640 value right so when you you index into a 5803 04:05:45,640 --> 04:05:48,720 string right so name is a single string 5804 04:05:48,720 --> 04:05:52,720 in go then it is a bite type um but we 5805 04:05:52,720 --> 04:05:54,439 want a rune type 5806 04:05:54,439 --> 04:05:56,840 so going go ahead and cast 5807 04:05:56,840 --> 04:06:00,399 it and run it 5808 04:06:01,720 --> 04:06:05,159 again cool uh Jing counts for 50 for the 5809 04:06:05,159 --> 04:06:08,720 first 50 names count for M Matthew is 5810 04:06:08,720 --> 04:06:12,680 three G George is One D Drew is four we 5811 04:06:12,680 --> 04:06:16,080 don't have any pan X so these counts 5812 04:06:16,080 --> 04:06:19,040 look totally plausible to me let's go 5813 04:06:19,040 --> 04:06:21,760 ahead and submit it it's time to talk 5814 04:06:21,760 --> 04:06:23,840 about first class and higher order 5815 04:06:23,840 --> 04:06:25,439 functions which are just really kind of 5816 04:06:25,439 --> 04:06:28,159 confusing complex terms for a much 5817 04:06:28,159 --> 04:06:32,279 simpler idea which is functions as data 5818 04:06:32,279 --> 04:06:33,840 a programming language is said to 5819 04:06:33,840 --> 04:06:36,319 support first class functions if it 5820 04:06:36,319 --> 04:06:39,080 allows you to pass around functions just 5821 04:06:39,080 --> 04:06:41,000 like you pass around any other variable 5822 04:06:41,000 --> 04:06:43,359 storing essentially an entire function 5823 04:06:43,359 --> 04:06:46,520 at as a value and then a function that 5824 04:06:46,520 --> 04:06:49,199 uses that first class function so a 5825 04:06:49,199 --> 04:06:51,479 function that accepts another function 5826 04:06:51,479 --> 04:06:54,399 as a parameter or returns a function as 5827 04:06:54,399 --> 04:06:56,760 a return value is said to be called a 5828 04:06:56,760 --> 04:06:59,239 higher order function let's take a look 5829 04:06:59,239 --> 04:07:02,080 at a concrete example okay so here we 5830 04:07:02,080 --> 04:07:04,840 have two functions add and multiply um 5831 04:07:04,840 --> 04:07:06,399 these are very simple functions you 5832 04:07:06,399 --> 04:07:08,359 should be able to understand uh what 5833 04:07:08,359 --> 04:07:10,560 they do just by looking at them for a 5834 04:07:10,560 --> 04:07:13,720 second um but here we have kind of an 5835 04:07:13,720 --> 04:07:15,159 interesting function it's called 5836 04:07:15,159 --> 04:07:19,720 Aggregate and it takes as input three 5837 04:07:19,720 --> 04:07:24,279 integers a b and c and it takes as input 5838 04:07:24,279 --> 04:07:27,159 an entire function right so it takes a 5839 04:07:27,159 --> 04:07:29,040 function and we're calling it here 5840 04:07:29,040 --> 04:07:31,680 arithmetic it's the fourth parameter to 5841 04:07:31,680 --> 04:07:34,279 the aggregate function and this function 5842 04:07:34,279 --> 04:07:36,800 has a specific signature this function 5843 04:07:36,800 --> 04:07:40,159 arithmetic must take as its parameters 5844 04:07:40,159 --> 04:07:41,159 two 5845 04:07:41,159 --> 04:07:43,920 integers right and return return an 5846 04:07:43,920 --> 04:07:46,159 integer itself and then the aggregate 5847 04:07:46,159 --> 04:07:48,479 function just returns an integer so what 5848 04:07:48,479 --> 04:07:51,520 does the aggregate function do well it 5849 04:07:51,520 --> 04:07:54,960 calls the function it was given Twice 5850 04:07:54,960 --> 04:07:58,199 first it calls it once with A and B and 5851 04:07:58,199 --> 04:08:00,880 then it calls it again with the results 5852 04:08:00,880 --> 04:08:04,159 of A and B and C so for example if we 5853 04:08:04,159 --> 04:08:07,880 call aggregate with the numbers 2 3 4 5854 04:08:07,880 --> 04:08:10,880 and the function add then it will add 5855 04:08:10,880 --> 04:08:12,560 all three of those numbers together 5856 04:08:12,560 --> 04:08:15,680 right which would in this case print n 5857 04:08:15,680 --> 04:08:17,239 and then we can also use that same 5858 04:08:17,239 --> 04:08:18,840 aggregate function with the same numbers 5859 04:08:18,840 --> 04:08:21,720 2 3 and four but this time pass in that 5860 04:08:21,720 --> 04:08:24,520 multiply function and here we'll get 24 5861 04:08:24,520 --> 04:08:26,520 right because we're multiplying um all 5862 04:08:26,520 --> 04:08:27,960 of the variables together instead of 5863 04:08:27,960 --> 04:08:30,159 adding them it's okay if this is a bit 5864 04:08:30,159 --> 04:08:32,359 confusing uh if this is the first time 5865 04:08:32,359 --> 04:08:35,040 you've worked with functions as data 5866 04:08:35,040 --> 04:08:36,960 take a second to really kind of stare at 5867 04:08:36,960 --> 04:08:39,680 this code and and figure out these this 5868 04:08:39,680 --> 04:08:41,880 crazy function signature um it's 5869 04:08:41,880 --> 04:08:43,640 actually not that complex once you kind 5870 04:08:43,640 --> 04:08:46,840 of get past the scary syntax um but but 5871 04:08:46,840 --> 04:08:48,119 don't feel bad if you have to pause the 5872 04:08:48,119 --> 04:08:50,399 video and take a good look let's get our 5873 04:08:50,399 --> 04:08:52,720 hands dirty with this assignment says 5874 04:08:52,720 --> 04:08:54,560 texo is launching a new email messaging 5875 04:08:54,560 --> 04:08:55,880 product 5876 04:08:55,880 --> 04:09:00,479 maleo I guess uh SMS and email right um 5877 04:09:00,479 --> 04:09:02,399 fix the compile time bug in the get 5878 04:09:02,399 --> 04:09:05,159 formatted messages function the function 5879 04:09:05,159 --> 04:09:06,560 body is correct but the function 5880 04:09:06,560 --> 04:09:09,439 signature is not okay so this formatter 5881 04:09:09,439 --> 04:09:12,000 function here looks like it will be a 5882 04:09:12,000 --> 04:09:13,560 problem let's go ahead and run the code 5883 04:09:13,560 --> 04:09:15,239 and see what kind of an error we get so 5884 04:09:15,239 --> 04:09:17,600 this is a compile time error uh saying 5885 04:09:17,600 --> 04:09:20,159 we have a syntax problem and that makes 5886 04:09:20,159 --> 04:09:21,640 sense because here we're we're basically 5887 04:09:21,640 --> 04:09:24,319 saying well the formatter input is a 5888 04:09:24,319 --> 04:09:26,560 function but we're not saying what type 5889 04:09:26,560 --> 04:09:29,359 of function it is and that doesn't work 5890 04:09:29,359 --> 04:09:31,080 because get formatted messages is going 5891 04:09:31,080 --> 04:09:33,000 to use the formatter function so it 5892 04:09:33,000 --> 04:09:34,720 needs to know essentially what 5893 04:09:34,720 --> 04:09:37,199 parameters it takes as input and what 5894 04:09:37,199 --> 04:09:39,560 it's going to return right uh kind of 5895 04:09:39,560 --> 04:09:41,960 like uh the arithmetic function here 5896 04:09:41,960 --> 04:09:44,159 takes two integers and returns an 5897 04:09:44,159 --> 04:09:46,279 integer uh we need to update this 5898 04:09:46,279 --> 04:09:49,000 function signature to kind of inform the 5899 04:09:49,000 --> 04:09:51,199 get formatted messages function what 5900 04:09:51,199 --> 04:09:53,399 this formatter function actually does so 5901 04:09:53,399 --> 04:09:55,960 if we look at the code because we know 5902 04:09:55,960 --> 04:09:59,920 the function body um is correct it looks 5903 04:09:59,920 --> 04:10:03,479 like formatter accepts a messages input 5904 04:10:03,479 --> 04:10:04,439 which is a 5905 04:10:04,439 --> 04:10:07,399 string and it's going to return whatever 5906 04:10:07,399 --> 04:10:09,239 should be appended to this formatted 5907 04:10:09,239 --> 04:10:10,840 messages slice which is a string so it 5908 04:10:10,840 --> 04:10:12,399 it looks like it takes one string as 5909 04:10:12,399 --> 04:10:14,720 input and and returns one string as 5910 04:10:14,720 --> 04:10:16,279 output that kind of makes sense for a 5911 04:10:16,279 --> 04:10:20,279 formatter function um so we say takes a 5912 04:10:20,279 --> 04:10:22,840 string and it returns a 5913 04:10:22,840 --> 04:10:24,960 string let's go ahead and run that and 5914 04:10:24,960 --> 04:10:27,960 see what we get cool at least it 5915 04:10:27,960 --> 04:10:30,080 compiled says thanks for getting back to 5916 04:10:30,080 --> 04:10:32,680 me which return thanks for getting back 5917 04:10:32,680 --> 04:10:34,119 to me kind 5918 04:10:34,119 --> 04:10:36,640 regards Okay cool so the ad signature 5919 04:10:36,640 --> 04:10:41,640 ads kinds to the end and add greeting 5920 04:10:41,640 --> 04:10:43,479 thanks for getting back to me hello 5921 04:10:43,479 --> 04:10:45,199 thanks for getting back to me cool let's 5922 04:10:45,199 --> 04:10:48,040 go ahead and run 5923 04:10:49,720 --> 04:10:53,800 that awesome so this might seem like an 5924 04:10:53,800 --> 04:10:56,560 exercise in complexity right like why do 5925 04:10:56,560 --> 04:10:58,520 I need to pass around functions as data 5926 04:10:58,520 --> 04:11:00,560 that just seems to add a bunch of well 5927 04:11:00,560 --> 04:11:02,439 needless complexity and for the most 5928 04:11:02,439 --> 04:11:04,960 part you're right you really should only 5929 04:11:04,960 --> 04:11:06,520 use higher order and first class 5930 04:11:06,520 --> 04:11:08,279 functions if you have a very good reason 5931 04:11:08,279 --> 04:11:10,479 to do so so the question is kind of what 5932 04:11:10,479 --> 04:11:13,920 are the good reasons to do so well first 5933 04:11:13,920 --> 04:11:15,239 class and higher order functions are 5934 04:11:15,239 --> 04:11:17,720 very often used for um on the back end 5935 04:11:17,720 --> 04:11:20,560 side of the stack HTTP handlers right so 5936 04:11:20,560 --> 04:11:21,960 if you have some front-end code that 5937 04:11:21,960 --> 04:11:23,920 needs to reach out to a backend server 5938 04:11:23,920 --> 04:11:26,720 and get some data those handlers are 5939 04:11:26,720 --> 04:11:29,439 typically first class or higher order 5940 04:11:29,439 --> 04:11:32,800 functions because we need some code 5941 04:11:32,800 --> 04:11:35,000 right the Handler function to run like 5942 04:11:35,000 --> 04:11:36,600 in the future we don't want to call it 5943 04:11:36,600 --> 04:11:38,359 now right we want to call it when 5944 04:11:38,359 --> 04:11:40,960 something happens in the UI World kind 5945 04:11:40,960 --> 04:11:42,640 of on the on the front end side of the 5946 04:11:42,640 --> 04:11:45,239 stack uh they're often used in onclick 5947 04:11:45,239 --> 04:11:47,479 handlers right so I write a function and 5948 04:11:47,479 --> 04:11:49,199 I don't necessarily call it when my 5949 04:11:49,199 --> 04:11:51,399 program starts but I call it when 5950 04:11:51,399 --> 04:11:52,800 something interesting happens like the 5951 04:11:52,800 --> 04:11:55,520 user clicks a button right when a button 5952 04:11:55,520 --> 04:11:58,080 click happens I want to call you know 5953 04:11:58,080 --> 04:12:00,760 this function and so typically in code 5954 04:12:00,760 --> 04:12:02,319 we can represent that with a higher 5955 04:12:02,319 --> 04:12:05,880 order function we say onclick do this 5956 04:12:05,880 --> 04:12:07,800 and then we kind of give it the name of 5957 04:12:07,800 --> 04:12:09,720 a function to call and then just to 5958 04:12:09,720 --> 04:12:12,040 review the definitions uh very quickly a 5959 04:12:12,040 --> 04:12:14,600 first class function is a function that 5960 04:12:14,600 --> 04:12:16,920 is kind of being passed around as data 5961 04:12:16,920 --> 04:12:19,439 and a higher order function is the 5962 04:12:19,439 --> 04:12:21,359 function that's using that first class 5963 04:12:21,359 --> 04:12:22,479 function right it's a function that 5964 04:12:22,479 --> 04:12:24,680 accepts a function as input or returns 5965 04:12:24,680 --> 04:12:27,159 it um as one of its return values so the 5966 04:12:27,159 --> 04:12:28,760 question is what is a higher order 5967 04:12:28,760 --> 04:12:31,000 function um it is a function that takes 5968 04:12:31,000 --> 04:12:33,439 another function as an argument or or 5969 04:12:33,439 --> 04:12:35,119 returns a function um but it's not a 5970 04:12:35,119 --> 04:12:36,560 function that is first in the call stack 5971 04:12:36,560 --> 04:12:40,399 or a function with Superior 5972 04:12:40,960 --> 04:12:43,720 logic so the next question is what is a 5973 04:12:43,720 --> 04:12:46,720 first class function um it is a function 5974 04:12:46,720 --> 04:12:48,720 that is treated like any other variable 5975 04:12:48,720 --> 04:12:49,920 right it's a function that we're going 5976 04:12:49,920 --> 04:12:53,000 to pass around as as data to probably be 5977 04:12:53,000 --> 04:12:55,439 called sometime in the future function 5978 04:12:55,439 --> 04:12:58,319 currying is kind of like a special kind 5979 04:12:58,319 --> 04:13:01,760 of higher order function it's a function 5980 04:13:01,760 --> 04:13:03,760 that accepts another function as input 5981 04:13:03,760 --> 04:13:05,720 we're kind of familiar with that idea 5982 04:13:05,720 --> 04:13:09,279 but that also returns a new function as 5983 04:13:09,279 --> 04:13:11,680 its output so it's kind of a way of like 5984 04:13:11,680 --> 04:13:14,760 enhancing a function with new Behavior 5985 04:13:14,760 --> 04:13:16,560 it's kind of a weird concept to think 5986 04:13:16,560 --> 04:13:18,720 about abstractly so let's jump into this 5987 04:13:18,720 --> 04:13:21,840 example okay so here we have a function 5988 04:13:21,840 --> 04:13:25,399 called self math and self math is the 5989 04:13:25,399 --> 04:13:27,239 curried function it takes a math 5990 04:13:27,239 --> 04:13:29,800 function as input that accepts two 5991 04:13:29,800 --> 04:13:32,479 integers and returns an integer and it 5992 04:13:32,479 --> 04:13:35,840 returns a new function that only takes a 5993 04:13:35,840 --> 04:13:38,000 single integer as input and returns an 5994 04:13:38,000 --> 04:13:40,479 integer and then what it does again it 5995 04:13:40,479 --> 04:13:42,119 returns a function right that takes a 5996 04:13:42,119 --> 04:13:44,359 single integer an input and returns an 5997 04:13:44,359 --> 04:13:46,479 integer and it calls the math function 5998 04:13:46,479 --> 04:13:49,880 that it was given with the same input 5999 04:13:49,880 --> 04:13:52,479 twice right so we're kind of mapping a 6000 04:13:52,479 --> 04:13:54,960 function that accepts two uh different 6001 04:13:54,960 --> 04:13:57,319 integers into a function that kind of 6002 04:13:57,319 --> 04:13:59,680 forces both of those integers to be the 6003 04:13:59,680 --> 04:14:02,439 same integer so like what does that do 6004 04:14:02,439 --> 04:14:04,680 in practice well basically we can use 6005 04:14:04,680 --> 04:14:08,439 our self math function to convert a 6006 04:14:08,439 --> 04:14:11,880 multiply function into a square function 6007 04:14:11,880 --> 04:14:14,040 right so multiply takes X and Y and 6008 04:14:14,040 --> 04:14:16,319 multiplies them together this new Square 6009 04:14:16,319 --> 04:14:18,600 function that we created dynamically 6010 04:14:18,600 --> 04:14:21,520 only takes a single value and multiplies 6011 04:14:21,520 --> 04:14:24,520 it by itself right um same with the add 6012 04:14:24,520 --> 04:14:26,600 function we can kind of use the self 6013 04:14:26,600 --> 04:14:28,720 maath function to convert it into a 6014 04:14:28,720 --> 04:14:31,080 function that just doubles its input 6015 04:14:31,080 --> 04:14:33,720 right so we Square Five we get 25 we 6016 04:14:33,720 --> 04:14:36,680 double five and we get 10 so when would 6017 04:14:36,680 --> 04:14:39,000 currying be used in the real world uh to 6018 04:14:39,000 --> 04:14:41,159 be honest I don't use it very often um 6019 04:14:41,159 --> 04:14:43,560 but in backend server land I do 6020 04:14:43,560 --> 04:14:45,399 sometimes use it for middleware 6021 04:14:45,399 --> 04:14:48,319 functions so a middleware function is a 6022 04:14:48,319 --> 04:14:50,840 function that basically changes the HTTP 6023 04:14:50,840 --> 04:14:53,760 Handler of a backend server um and just 6024 04:14:53,760 --> 04:14:56,000 as a spoiler we will be covering this in 6025 04:14:56,000 --> 04:14:58,600 the project at the end of this course um 6026 04:14:58,600 --> 04:15:01,000 but it's for kind of injecting some 6027 04:15:01,000 --> 04:15:03,399 additional logic into a function so say 6028 04:15:03,399 --> 04:15:06,199 we have an HTTP Handler that accepts as 6029 04:15:06,199 --> 04:15:09,159 input a user ID and returns an entire 6030 04:15:09,159 --> 04:15:11,080 user object with you know say their 6031 04:15:11,080 --> 04:15:12,720 first name their last name that sort of 6032 04:15:12,720 --> 04:15:13,640 thing 6033 04:15:13,640 --> 04:15:15,960 um a middleware function might do 6034 04:15:15,960 --> 04:15:18,159 something like require an authentication 6035 04:15:18,159 --> 04:15:20,520 token right so we can write all of our 6036 04:15:20,520 --> 04:15:23,119 HTTP handlers that serve different data 6037 04:15:23,119 --> 04:15:25,119 sort of independently and then we can 6038 04:15:25,119 --> 04:15:27,960 use a curried function to kind of 6039 04:15:27,960 --> 04:15:30,560 require authentication Logic on all of 6040 04:15:30,560 --> 04:15:34,119 our HTTP handlers um in fact in go 6041 04:15:34,119 --> 04:15:36,760 currying is very often used to handle 6042 04:15:36,760 --> 04:15:39,319 the sort of middleware problem now if 6043 04:15:39,319 --> 04:15:41,239 all of that went straight over your head 6044 04:15:41,239 --> 04:15:43,319 again that's okay it's kind of hard to 6045 04:15:43,319 --> 04:15:45,479 talk about um something that we're not 6046 04:15:45,479 --> 04:15:47,520 working on at the moment so again we're 6047 04:15:47,520 --> 04:15:49,920 going to cover middleware and HTTP 6048 04:15:49,920 --> 04:15:51,520 handlers in the project at the end of 6049 04:15:51,520 --> 04:15:53,600 this course so stick around for that so 6050 04:15:53,600 --> 04:15:55,640 jumping into the assignment it says the 6051 04:15:55,640 --> 04:15:58,399 maleo API needs a very robust error 6052 04:15:58,399 --> 04:16:00,119 logging system so we can see when things 6053 04:16:00,119 --> 04:16:02,560 are going arai in the back end we need a 6054 04:16:02,560 --> 04:16:05,159 function that can create a custom logger 6055 04:16:05,159 --> 04:16:07,359 a function that prints to the console 6056 04:16:07,359 --> 04:16:10,199 given a specific formatter Okay cool so 6057 04:16:10,199 --> 04:16:13,359 this function get logger should return a 6058 04:16:13,359 --> 04:16:15,880 logger which is a function right it's a 6059 04:16:15,880 --> 04:16:19,199 function that takes two strings as input 6060 04:16:19,199 --> 04:16:21,399 and apparently prints them because it 6061 04:16:21,399 --> 04:16:24,560 doesn't return anything right and get 6062 04:16:24,560 --> 04:16:27,040 logger takes as input a formatter which 6063 04:16:27,040 --> 04:16:29,680 accepts two strings as input and returns 6064 04:16:29,680 --> 04:16:31,040 a single 6065 04:16:31,040 --> 04:16:32,960 string okay so it says complete the get 6066 04:16:32,960 --> 04:16:34,279 logger function it should return a new 6067 04:16:34,279 --> 04:16:36,439 function um the inputs should be passed 6068 04:16:36,439 --> 04:16:37,760 into the format or function the order 6069 04:16:37,760 --> 04:16:40,159 they given to the loger function okay 6070 04:16:40,159 --> 04:16:42,960 so let's start writing this so we're 6071 04:16:42,960 --> 04:16:44,840 going to return a 6072 04:16:44,840 --> 04:16:49,439 function that takes two strings as input 6073 04:16:49,439 --> 04:16:52,680 right and I'm going to reference up here 6074 04:16:52,680 --> 04:16:54,720 for the syntax we're interested in so 6075 04:16:54,720 --> 04:16:56,840 I'm going to do a 6076 04:16:56,840 --> 04:17:02,319 string B string all right and this 6077 04:17:02,319 --> 04:17:04,279 function should return nothing so we can 6078 04:17:04,279 --> 04:17:05,680 just go straight into the 6079 04:17:05,680 --> 04:17:07,800 body and it 6080 04:17:07,800 --> 04:17:10,399 says this function prints the formatted 6081 04:17:10,399 --> 04:17:13,199 inputs so formatter returns a single 6082 04:17:13,199 --> 04:17:16,040 string so we can just do fmt do print 6083 04:17:16,040 --> 04:17:18,279 line and we're going to need to oh we 6084 04:17:18,279 --> 04:17:21,720 already have fmt imported perfect so we 6085 04:17:21,720 --> 04:17:24,000 need to print the result of the 6086 04:17:24,000 --> 04:17:25,760 formatter functions it's going to be 6087 04:17:25,760 --> 04:17:29,760 formatter and we'll pass into the format 6088 04:17:29,760 --> 04:17:32,680 A and 6089 04:17:33,560 --> 04:17:35,840 B right so we're returning a new 6090 04:17:35,840 --> 04:17:39,119 function a logger that accepts two 6091 04:17:39,119 --> 04:17:42,960 inputs formats them given the formatter 6092 04:17:42,960 --> 04:17:45,000 that we were given right and then just 6093 04:17:45,000 --> 04:17:47,199 prints it to the console cool let's go 6094 04:17:47,199 --> 04:17:49,680 ahead and run 6095 04:17:51,040 --> 04:17:53,439 that error on database server out of 6096 04:17:53,439 --> 04:17:55,800 memory error on database server CPU is 6097 04:17:55,800 --> 04:17:58,319 pegged this all looks good let's see how 6098 04:17:58,319 --> 04:17:59,960 the test site actually 6099 04:17:59,960 --> 04:18:02,159 works it looks like these are the 6100 04:18:02,159 --> 04:18:04,439 formatters colon delimit and comma 6101 04:18:04,439 --> 04:18:06,239 delimit and if you take a look at our 6102 04:18:06,239 --> 04:18:08,800 messages some are delimited by a colon 6103 04:18:08,800 --> 04:18:11,520 some are delimited by a 6104 04:18:11,520 --> 04:18:15,680 comma so that's how that is working very 6105 04:18:15,680 --> 04:18:16,960 cool all right I'm going to go ahead and 6106 04:18:16,960 --> 04:18:19,000 submit that I think this is 6107 04:18:19,000 --> 04:18:21,279 correct time to talk about the defer 6108 04:18:21,279 --> 04:18:23,920 keyword uh this is a really kind of 6109 04:18:23,920 --> 04:18:26,800 unique thing to go um if you're familiar 6110 04:18:26,800 --> 04:18:28,319 with any other programming languages 6111 04:18:28,319 --> 04:18:30,800 it's unlikely um that you're familiar 6112 04:18:30,800 --> 04:18:33,040 with something similar to the defer 6113 04:18:33,040 --> 04:18:35,680 keyword um at least I've never used it 6114 04:18:35,680 --> 04:18:39,040 or used a concept uh that is similar to 6115 04:18:39,040 --> 04:18:41,640 the defer keyword in another language um 6116 04:18:41,640 --> 04:18:43,399 fairly go specific 6117 04:18:43,399 --> 04:18:46,359 okay so the defer keyword allows us to 6118 04:18:46,359 --> 04:18:50,040 execute some function at the end of the 6119 04:18:50,040 --> 04:18:51,720 current function or when the current 6120 04:18:51,720 --> 04:18:55,080 function exits the defer keyword is very 6121 04:18:55,080 --> 04:18:57,800 often used as sort of a cleanup step um 6122 04:18:57,800 --> 04:19:00,119 for example in this in this function 6123 04:19:00,119 --> 04:19:01,520 here copy 6124 04:19:01,520 --> 04:19:05,000 file we open a source file from the file 6125 04:19:05,000 --> 04:19:08,279 system and then we defer closing the 6126 04:19:08,279 --> 04:19:11,359 file right so every time you open access 6127 04:19:11,359 --> 04:19:13,040 to a file in the file system you need to 6128 04:19:13,040 --> 04:19:15,520 remember to close that file otherwise 6129 04:19:15,520 --> 04:19:17,319 you're sort of wasting Computer 6130 04:19:17,319 --> 04:19:21,560 Resources um the problem is closing the 6131 04:19:21,560 --> 04:19:23,399 file at the end of the function is a 6132 04:19:23,399 --> 04:19:25,239 little tedious because we have multiple 6133 04:19:25,239 --> 04:19:26,880 return statements here so we'd kind of 6134 04:19:26,880 --> 04:19:28,880 have to close it before both of them if 6135 04:19:28,880 --> 04:19:30,640 that makes sense by using the defer 6136 04:19:30,640 --> 04:19:32,560 keyword we can just tell the go 6137 04:19:32,560 --> 04:19:34,680 programming language hey I want to call 6138 04:19:34,680 --> 04:19:35,880 source. 6139 04:19:35,880 --> 04:19:38,600 close right before the copy file 6140 04:19:38,600 --> 04:19:41,359 function ends and just defers it kind of 6141 04:19:41,359 --> 04:19:43,319 until the end and it will only call it 6142 04:19:43,319 --> 04:19:46,040 once um no matter where the function 6143 04:19:46,040 --> 04:19:48,439 actually returns from on to the 6144 04:19:48,439 --> 04:19:50,439 assignment it says there is a bug in the 6145 04:19:50,439 --> 04:19:52,640 log and delete function fix it let me 6146 04:19:52,640 --> 04:19:54,239 expand this a little bit so we can see 6147 04:19:54,239 --> 04:19:56,560 it this function should always delete 6148 04:19:56,560 --> 04:19:58,720 the user from the users map Okay cool so 6149 04:19:58,720 --> 04:20:00,399 we're given a user's map we're given a 6150 04:20:00,399 --> 04:20:03,520 name and we know that Maps uh are passed 6151 04:20:03,520 --> 04:20:06,159 by reference so if we delete a map uh it 6152 04:20:06,159 --> 04:20:10,760 will be deleted in the callers code as 6153 04:20:10,760 --> 04:20:13,359 well um it should return log string that 6154 04:20:13,359 --> 04:20:14,720 indicates to the caller some information 6155 04:20:14,720 --> 04:20:17,359 about the user's deletion okay so delete 6156 04:20:17,359 --> 04:20:19,279 should always happen and then the kind 6157 04:20:19,279 --> 04:20:22,720 of the appropriate log message should be 6158 04:20:22,720 --> 04:20:24,760 returned from the function that makes 6159 04:20:24,760 --> 04:20:26,920 sense um but it looks like there's a bug 6160 04:20:26,920 --> 04:20:28,000 okay so let's go ahead and run the code 6161 04:20:28,000 --> 04:20:30,520 and see what we 6162 04:20:31,119 --> 04:20:34,279 get so initial users Brianna Elon John 6163 04:20:34,279 --> 04:20:37,600 Cade attempting to delete John deleting 6164 04:20:37,600 --> 04:20:39,760 Santa deleting 6165 04:20:39,760 --> 04:20:42,680 Cade okay so John's still there the 6166 04:20:42,680 --> 04:20:45,080 problem is that we're trying to delete 6167 04:20:45,080 --> 04:20:47,439 JN but Jon's not actually getting 6168 04:20:47,439 --> 04:20:49,800 deleted right so we need to fix that 6169 04:20:49,800 --> 04:20:55,199 bug and if we take a look John is an 6170 04:20:55,199 --> 04:20:59,439 admin and here we are returning log 6171 04:20:59,439 --> 04:21:02,199 admin but we're not deleting admins so 6172 04:21:02,199 --> 04:21:03,880 so that's that's the real problem right 6173 04:21:03,880 --> 04:21:05,760 the users should always be 6174 04:21:05,760 --> 04:21:09,600 deleted now here's the problem we can do 6175 04:21:09,600 --> 04:21:14,600 this um this will work if I run this my 6176 04:21:14,600 --> 04:21:16,840 guess is this should fix the bug yep JN 6177 04:21:16,840 --> 04:21:18,920 is no longer there he was deleted 6178 04:21:18,920 --> 04:21:21,800 successfully but this is kind of gross 6179 04:21:21,800 --> 04:21:23,520 right we we're calling delete three 6180 04:21:23,520 --> 04:21:26,720 different times um what if in the future 6181 04:21:26,720 --> 04:21:29,399 we add another case and we forget we 6182 04:21:29,399 --> 04:21:30,920 forget to add the delete again we'll 6183 04:21:30,920 --> 04:21:34,319 have another bug um well what we could 6184 04:21:34,319 --> 04:21:37,479 do what we could do is just delete at 6185 04:21:37,479 --> 04:21:38,560 the top 6186 04:21:38,560 --> 04:21:40,680 once 6187 04:21:40,680 --> 04:21:44,199 right but the problem is if we do 6188 04:21:44,199 --> 04:21:47,239 that we delete the user from the users 6189 04:21:47,239 --> 04:21:50,680 map too soon and now this okay variable 6190 04:21:50,680 --> 04:21:52,359 that's checking for existence so it can 6191 04:21:52,359 --> 04:21:54,840 change which log is returned like that 6192 04:21:54,840 --> 04:21:57,159 logic won't work it will just always be 6193 04:21:57,159 --> 04:21:59,479 not okay so we'll always just return log 6194 04:21:59,479 --> 04:22:02,600 not found so that's a problem what we 6195 04:22:02,600 --> 04:22:06,880 can do is defer the deletion so this 6196 04:22:06,880 --> 04:22:08,840 code says we'll call this delete 6197 04:22:08,840 --> 04:22:11,600 function right before login delete 6198 04:22:11,600 --> 04:22:14,640 returns so it it's almost like um the 6199 04:22:14,640 --> 04:22:17,119 equivalent of you know adding this at 6200 04:22:17,119 --> 04:22:18,880 every step of the way so let's go ahead 6201 04:22:18,880 --> 04:22:21,800 and run that make sure it 6202 04:22:22,119 --> 04:22:25,720 works John's there John's gone perfect 6203 04:22:25,720 --> 04:22:28,760 and we have different logs getting 6204 04:22:28,760 --> 04:22:29,800 returned so that looks good I'm going to 6205 04:22:29,800 --> 04:22:32,159 go ahead and submit that this chapter is 6206 04:22:32,159 --> 04:22:35,359 not called Advanced functions uh for no 6207 04:22:35,359 --> 04:22:37,600 reason let's talk about closures 6208 04:22:37,600 --> 04:22:40,239 closures are um I don't want to like 6209 04:22:40,239 --> 04:22:41,560 intimidate you and say they're really 6210 04:22:41,560 --> 04:22:43,479 hard but they're a little weird so let's 6211 04:22:43,479 --> 04:22:45,840 let's take a second to understand uh how 6212 04:22:45,840 --> 04:22:48,119 they work okay a closure is a function 6213 04:22:48,119 --> 04:22:49,960 that references variables from outside 6214 04:22:49,960 --> 04:22:52,199 its own function body the function May 6215 04:22:52,199 --> 04:22:53,600 access and assign to the referenced 6216 04:22:53,600 --> 04:22:57,960 variables so in this example the concat 6217 04:22:57,960 --> 04:23:00,080 function returns a function that has a 6218 04:23:00,080 --> 04:23:02,319 reference to the enclosed doc value okay 6219 04:23:02,319 --> 04:23:06,159 so concat is a function it returns a new 6220 04:23:06,159 --> 04:23:07,960 function right and that's what's 6221 04:23:07,960 --> 04:23:10,359 happening 6222 04:23:10,479 --> 04:23:14,960 here and it's enclosed using this doc 6223 04:23:14,960 --> 04:23:17,239 string within the function so it's 6224 04:23:17,239 --> 04:23:19,040 getting initialized outside of the 6225 04:23:19,040 --> 04:23:20,760 function and then getting used within 6226 04:23:20,760 --> 04:23:24,359 the function and what happens is 6227 04:23:24,359 --> 04:23:27,920 basically when we call concat to to make 6228 04:23:27,920 --> 04:23:30,960 this new like concat 6229 04:23:30,960 --> 04:23:33,600 function we're saving a reference to 6230 04:23:33,600 --> 04:23:36,840 this doc variable so every kind of 6231 04:23:36,840 --> 04:23:39,640 concurrent not concurrent every uh 6232 04:23:39,640 --> 04:23:43,000 subsequent call to this function that is 6233 04:23:43,000 --> 04:23:46,600 returned we'll keep adding on right plus 6234 04:23:46,600 --> 04:23:49,359 equals word we'll keep adding on to the 6235 04:23:49,359 --> 04:23:51,720 same doc variable so let's look at what 6236 04:23:51,720 --> 04:23:54,760 that uh kind of looks like in usage so 6237 04:23:54,760 --> 04:23:57,040 we're calling concat and we're getting 6238 04:23:57,040 --> 04:23:59,359 back this Harry Potter aggregator right 6239 04:23:59,359 --> 04:24:02,199 that's what we're assigning this 6240 04:24:02,199 --> 04:24:04,600 function we're assigning this function 6241 04:24:04,600 --> 04:24:06,720 into this variable so Harry Potter 6242 04:24:06,720 --> 04:24:09,159 aggregator is a function right it's it's 6243 04:24:09,159 --> 04:24:10,560 specifically it's this function right 6244 04:24:10,560 --> 04:24:12,640 here cool and then we're going to call 6245 04:24:12,640 --> 04:24:15,279 it with mis and then we'll call it again 6246 04:24:15,279 --> 04:24:18,040 with and and Mrs dersley Right we're 6247 04:24:18,040 --> 04:24:19,520 calling it over and over and over and 6248 04:24:19,520 --> 04:24:21,080 what's happening under the hood is we 6249 04:24:21,080 --> 04:24:24,920 are appending those words Mr and Mrs 6250 04:24:24,920 --> 04:24:27,760 onto that doc variable so at the end 6251 04:24:27,760 --> 04:24:29,560 when we finally 6252 04:24:29,560 --> 04:24:32,479 print what's being returned which is the 6253 04:24:32,479 --> 04:24:35,119 doc variable itself we get the full 6254 04:24:35,119 --> 04:24:37,279 sentence Mr and Mrs Durley of number 6255 04:24:37,279 --> 04:24:39,680 four privet drive now closures are one 6256 04:24:39,680 --> 04:24:42,040 of those Advanced things that you to be 6257 04:24:42,040 --> 04:24:44,479 honest again don't usually use in 6258 04:24:44,479 --> 04:24:46,319 production code maybe every once in a 6259 04:24:46,319 --> 04:24:48,560 while um but they're very important to 6260 04:24:48,560 --> 04:24:51,199 understand because it is very common to 6261 04:24:51,199 --> 04:24:54,000 have kind of bugs surrounding closures 6262 04:24:54,000 --> 04:24:55,359 so if you don't understand what's going 6263 04:24:55,359 --> 04:24:57,000 on under the hood it can be really hard 6264 04:24:57,000 --> 04:25:00,000 to debug kind of complex code that might 6265 04:25:00,000 --> 04:25:02,840 even be using closures by accident so 6266 04:25:02,840 --> 04:25:04,880 the assignment says keeping track of how 6267 04:25:04,880 --> 04:25:06,960 many emails we send is Mission critical 6268 04:25:06,960 --> 04:25:10,040 at maleo complete the adder function 6269 04:25:10,040 --> 04:25:11,960 it's return a function that adds its 6270 04:25:11,960 --> 04:25:14,840 input an integer to an enclosed sum 6271 04:25:14,840 --> 04:25:16,960 value and then Returns the new sum in 6272 04:25:16,960 --> 04:25:18,399 other words it keeps a running total of 6273 04:25:18,399 --> 04:25:20,760 the sum variable uh within a closure 6274 04:25:20,760 --> 04:25:21,920 Okay cool so it's going to be very 6275 04:25:21,920 --> 04:25:24,119 similar to this right so we'll start by 6276 04:25:24,119 --> 04:25:26,760 creating a sum value so sum colon equals 6277 04:25:26,760 --> 04:25:28,279 zero right we're we're working with 6278 04:25:28,279 --> 04:25:31,040 integers not flows and then we need to 6279 04:25:31,040 --> 04:25:33,640 return a function with the signature so 6280 04:25:33,640 --> 04:25:39,720 return Funk X int returns an 6281 04:25:39,720 --> 04:25:42,920 INT oh not not returns an X returns an 6282 04:25:42,920 --> 04:25:47,279 INT and then here we need to add X to 6283 04:25:47,279 --> 04:25:50,560 sum right so sum plus equals 6284 04:25:50,560 --> 04:25:53,159 X and then we need to 6285 04:25:53,159 --> 04:25:55,199 return the new 6286 04:25:55,199 --> 04:25:57,920 sum right and then if we go take a look 6287 04:25:57,920 --> 04:26:02,760 at this test case let's 6288 04:26:03,800 --> 04:26:07,760 see okay so we're adding these email 6289 04:26:07,760 --> 04:26:10,279 bills with a bunch of different 6290 04:26:10,279 --> 04:26:14,119 numbers the test Ates over the bills ah 6291 04:26:14,119 --> 04:26:15,840 okay so we're creating two adders here 6292 04:26:15,840 --> 04:26:17,840 so we're creating a count adder and a 6293 04:26:17,840 --> 04:26:19,319 cost 6294 04:26:19,319 --> 04:26:22,840 adder and then let me expand 6295 04:26:22,840 --> 04:26:25,119 this going to just make that basically 6296 04:26:25,119 --> 04:26:26,399 full 6297 04:26:26,399 --> 04:26:29,119 screen so the test actually creates two 6298 04:26:29,119 --> 04:26:31,159 different adders two different instances 6299 04:26:31,159 --> 04:26:33,720 of our Adder function right and one of 6300 04:26:33,720 --> 04:26:36,479 them is going to count how many bills 6301 04:26:36,479 --> 04:26:38,800 there are and the other one will keep a 6302 04:26:38,800 --> 04:26:42,040 running total of the cost of all of the 6303 04:26:42,040 --> 04:26:43,119 builds 6304 04:26:43,119 --> 04:26:45,199 right so we're actually using our 6305 04:26:45,199 --> 04:26:47,319 function twice for two different things 6306 04:26:47,319 --> 04:26:50,600 and they'll each have their own enclosed 6307 04:26:50,600 --> 04:26:53,279 some count that they keep track of 6308 04:26:53,279 --> 04:26:54,560 differently right the count will have 6309 04:26:54,560 --> 04:26:56,239 its own the cost will have its own the 6310 04:26:56,239 --> 04:26:58,000 count is simple it just adds one every 6311 04:26:58,000 --> 04:27:00,119 time the cost will add the actual cost 6312 04:27:00,119 --> 04:27:04,319 in pennies cool let's go ahead and run 6313 04:27:05,080 --> 04:27:08,080 this so um and these values are getting 6314 04:27:08,080 --> 04:27:10,040 interpolated into this message so youve 6315 04:27:10,040 --> 04:27:13,080 sent one email cost 45 cents two emails 6316 04:27:13,080 --> 04:27:16,479 77 cents three emails 120 cents so like 6317 04:27:16,479 --> 04:27:18,000 all of these are going up that makes 6318 04:27:18,000 --> 04:27:19,439 sense I mean we could even go verify 6319 04:27:19,439 --> 04:27:23,840 right 45 + 32 77 that looks right to me 6320 04:27:23,840 --> 04:27:26,319 let's go ahead and submit it all right 6321 04:27:26,319 --> 04:27:28,560 we're on to a little quiz about closures 6322 04:27:28,560 --> 04:27:31,000 can a closure mutate a variable outside 6323 04:27:31,000 --> 04:27:34,199 of its body uh yes that's basically the 6324 04:27:34,199 --> 04:27:36,760 entire point of a closure another little 6325 04:27:36,760 --> 04:27:38,800 review question here says when a 6326 04:27:38,800 --> 04:27:40,960 variable is enclosed in a closure the 6327 04:27:40,960 --> 04:27:44,479 enclosing function has access to blank a 6328 04:27:44,479 --> 04:27:47,159 copy of the value or a mutable reference 6329 04:27:47,159 --> 04:27:49,720 to the original value well if it was a 6330 04:27:49,720 --> 04:27:51,800 copy then our sum never would have 6331 04:27:51,800 --> 04:27:53,000 worked right because we'd be working 6332 04:27:53,000 --> 04:27:54,560 with a new copy of the sum variable 6333 04:27:54,560 --> 04:27:56,439 every time so it's actually a mutable 6334 04:27:56,439 --> 04:27:58,720 reference to the original value we've 6335 04:27:58,720 --> 04:28:00,880 already been using Anonymous functions 6336 04:28:00,880 --> 04:28:02,840 kind of all throughout this chapter um 6337 04:28:02,840 --> 04:28:04,199 now let's kind of just talk about what 6338 04:28:04,199 --> 04:28:06,359 they are so Anonymous functions are 6339 04:28:06,359 --> 04:28:07,560 exactly what they sound like they're 6340 04:28:07,560 --> 04:28:09,880 just functions that do not have a name 6341 04:28:09,880 --> 04:28:12,840 they have no name um Anonymous functions 6342 04:28:12,840 --> 04:28:14,080 are really useful when you're kind of 6343 04:28:14,080 --> 04:28:16,800 just oneoff maybe creating a closure 6344 04:28:16,800 --> 04:28:19,119 you're returning a new type of function 6345 04:28:19,119 --> 04:28:21,800 um if if you're not defining the 6346 04:28:21,800 --> 04:28:23,720 function for like use across the entire 6347 04:28:23,720 --> 04:28:25,199 program but you're more using it as a 6348 04:28:25,199 --> 04:28:27,279 value using it as a first class function 6349 04:28:27,279 --> 04:28:28,520 um that's when you're going to see 6350 04:28:28,520 --> 04:28:31,119 Anonymous functions use the most so as 6351 04:28:31,119 --> 04:28:35,720 an example um here we have an anonymous 6352 04:28:35,720 --> 04:28:37,640 function declaration right we're 6353 04:28:37,640 --> 04:28:39,600 creating a new function we're defining 6354 04:28:39,600 --> 04:28:41,560 its internal logic it's its function 6355 04:28:41,560 --> 04:28:44,080 body um but we're not giving it a name 6356 04:28:44,080 --> 04:28:45,960 right there's no name uh for this 6357 04:28:45,960 --> 04:28:48,439 function that we're passing into do math 6358 04:28:48,439 --> 04:28:50,399 it is an anonymous function the 6359 04:28:50,399 --> 04:28:52,399 assignment says complete the print 6360 04:28:52,399 --> 04:28:55,359 reports function call Print cost report 6361 04:28:55,359 --> 04:28:57,600 once for each message okay let's take a 6362 04:28:57,600 --> 04:29:00,560 look print cost report looks like it 6363 04:29:00,560 --> 04:29:04,119 takes as input a function cost 6364 04:29:04,119 --> 04:29:08,119 calculator great okay um call Print cost 6365 04:29:08,119 --> 04:29:09,760 report once for each message pass an 6366 04:29:09,760 --> 04:29:11,040 anonymous function as the cost 6367 04:29:11,040 --> 04:29:13,040 calculator that returns an int equal to 6368 04:29:13,040 --> 04:29:15,279 twice the length of the input message 6369 04:29:15,279 --> 04:29:18,239 okay let's go ahead and do that 6370 04:29:18,239 --> 04:29:20,359 so um it says to do it once for each 6371 04:29:20,359 --> 04:29:21,840 message yeah so 6372 04:29:21,840 --> 04:29:24,000 four 6373 04:29:24,000 --> 04:29:27,800 message range 6374 04:29:30,040 --> 04:29:33,119 messages call Print cost report print 6375 04:29:33,119 --> 04:29:34,800 cost 6376 04:29:34,800 --> 04:29:37,840 report and print cost report takes a 6377 04:29:37,840 --> 04:29:41,600 cost calculator which is a function that 6378 04:29:41,600 --> 04:29:43,640 takes us string and returns an 6379 04:29:43,640 --> 04:29:46,319 INT said to use an anonymous function 6380 04:29:46,319 --> 04:29:48,239 right so funks we need to actually 6381 04:29:48,239 --> 04:29:52,040 Define our X string int we need to 6382 04:29:52,040 --> 04:29:55,119 define the body um that returns an INT 6383 04:29:55,119 --> 04:29:56,840 equal to twice the length of the input 6384 04:29:56,840 --> 04:29:59,080 message so X is a string in fact I'm 6385 04:29:59,080 --> 04:30:02,960 going to name this um message and we'll 6386 04:30:02,960 --> 04:30:05,119 return the length of 6387 04:30:05,119 --> 04:30:07,439 message time 6388 04:30:07,439 --> 04:30:09,840 2 right twice the length of the input 6389 04:30:09,840 --> 04:30:11,840 message and then print cost report takes 6390 04:30:11,840 --> 04:30:15,000 us second parameter which is the message 6391 04:30:15,000 --> 04:30:18,000 itself 6392 04:30:18,520 --> 04:30:20,920 right I think am I am I reading this 6393 04:30:20,920 --> 04:30:24,359 correctly cost report FES the calculator 6394 04:30:24,359 --> 04:30:25,920 and the message itself yep because it's 6395 04:30:25,920 --> 04:30:27,199 going to it's then going to call the 6396 04:30:27,199 --> 04:30:29,199 cost calculator and then and then print 6397 04:30:29,199 --> 04:30:32,800 kind of a little report okay cool um 6398 04:30:32,800 --> 04:30:36,279 that's looking pretty good to me we 6399 04:30:36,279 --> 04:30:38,720 don't return anything from print reports 6400 04:30:38,720 --> 04:30:42,680 okay let's go ahead and run this 6401 04:30:43,399 --> 04:30:46,920 so message here's Johnny cost 28 cents 6402 04:30:46,920 --> 04:30:49,359 go ahead make my day 42 cents you had me 6403 04:30:49,359 --> 04:30:51,640 at hello 38 cents that's looking correct 6404 04:30:51,640 --> 04:30:53,359 right there's 6405 04:30:53,359 --> 04:30:54,880 19 6406 04:30:54,880 --> 04:30:58,239 28 not 19 what's half of 28 14 14 6407 04:30:58,239 --> 04:31:00,760 characters there looks good to me okay 6408 04:31:00,760 --> 04:31:02,720 let's go ahead and submit 6409 04:31:02,720 --> 04:31:05,640 that let's talk about pointers and in 6410 04:31:05,640 --> 04:31:07,800 order to understand pointers we need to 6411 04:31:07,800 --> 04:31:10,920 um talk a little bit about Ram or memory 6412 04:31:10,920 --> 04:31:12,920 right Random Access memory which is 6413 04:31:12,920 --> 04:31:14,680 basically the part of the hardware in 6414 04:31:14,680 --> 04:31:17,520 our computer that stores data right 6415 04:31:17,520 --> 04:31:19,680 because pointers and variables are all 6416 04:31:19,680 --> 04:31:22,680 about kind of how we store data in the 6417 04:31:22,680 --> 04:31:24,640 memory of our computer let's start with 6418 04:31:24,640 --> 04:31:25,800 something 6419 04:31:25,800 --> 04:31:29,000 simple let's create a new variable in 6420 04:31:29,000 --> 04:31:30,359 our 6421 04:31:30,359 --> 04:31:33,479 program and let's call it X and we'll 6422 04:31:33,479 --> 04:31:35,080 set x equal to 6423 04:31:35,080 --> 04:31:37,560 5 under the hood what happens 6424 04:31:37,560 --> 04:31:38,960 automatically when we create a new 6425 04:31:38,960 --> 04:31:41,279 variable uh and set it equal to five is 6426 04:31:41,279 --> 04:31:44,920 somewhere in our computer's memory that 6427 04:31:44,920 --> 04:31:47,080 variable's value is going to get stored 6428 04:31:47,080 --> 04:31:49,560 so let's say uh for the sake of the 6429 04:31:49,560 --> 04:31:52,119 example that it's stored here in memory 6430 04:31:52,119 --> 04:31:55,520 address 169 Now Memory in your computer 6431 04:31:55,520 --> 04:31:58,239 you could think of it as fairly simply a 6432 04:31:58,239 --> 04:32:00,880 memory address that stores a value so 6433 04:32:00,880 --> 04:32:02,720 we've got kind of you know millions of 6434 04:32:02,720 --> 04:32:04,239 different memory addresses in which we 6435 04:32:04,239 --> 04:32:08,479 can store data and somewhere in memory 6436 04:32:08,479 --> 04:32:10,239 uh that value needs to live so let's 6437 04:32:10,239 --> 04:32:11,880 just say it gets assigned again automat 6438 04:32:11,880 --> 04:32:17,119 aut atically um to address 169 great now 6439 04:32:17,119 --> 04:32:19,359 what happens if I create a new variable 6440 04:32:19,359 --> 04:32:22,680 let's call it Y and set it equal to the 6441 04:32:22,680 --> 04:32:24,720 current value of 6442 04:32:24,720 --> 04:32:29,600 x y actually gets a new copy of the 6443 04:32:29,600 --> 04:32:34,359 value so X lives here at address 169 y 6444 04:32:34,359 --> 04:32:35,800 let's just say is going to live at 6445 04:32:35,800 --> 04:32:38,319 address 170 and we get a copy of that 6446 04:32:38,319 --> 04:32:40,439 five so down here in this table this is 6447 04:32:40,439 --> 04:32:42,279 where we're going to keep track of all 6448 04:32:42,279 --> 04:32:46,159 of our variables we'll say that X so X 6449 04:32:46,159 --> 04:32:50,119 is the variable name lives at address 6450 04:32:50,119 --> 04:32:53,840 169 and it stores the value 6451 04:32:53,840 --> 04:32:55,720 five now 6452 04:32:55,720 --> 04:32:59,399 y lives at address 6453 04:32:59,399 --> 04:33:04,320 170 and stores also the value five at 6454 04:33:04,320 --> 04:33:07,879 its most basic a pointer is just a 6455 04:33:07,879 --> 04:33:11,959 variable that stores a memory address so 6456 04:33:11,959 --> 04:33:14,799 let's say for example that we create a 6457 04:33:14,799 --> 04:33:16,561 new variable called 6458 04:33:16,561 --> 04:33:20,879 Z and we set it to point which is uh 6459 04:33:20,879 --> 04:33:23,199 which uses the Ampersand I can't draw an 6460 04:33:23,199 --> 04:33:25,119 ampersand pretend that that's an 6461 04:33:25,119 --> 04:33:28,320 ampersand uh the the the a reference to 6462 04:33:28,320 --> 04:33:32,320 X right it points to x what that does is 6463 04:33:32,320 --> 04:33:33,719 that we're creating a new variable 6464 04:33:33,719 --> 04:33:34,920 called 6465 04:33:34,920 --> 04:33:37,920 Z it's going to get a new address 6466 04:33:37,920 --> 04:33:39,480 anytime we create a new variable it's 6467 04:33:39,480 --> 04:33:41,439 going to live in a new address in memory 6468 04:33:41,439 --> 04:33:44,000 let's say it lives at address 6469 04:33:44,000 --> 04:33:47,039 171 but its value instead of being five 6470 04:33:47,039 --> 04:33:49,279 instead of being a copy of X because we 6471 04:33:49,279 --> 04:33:51,680 used kind of the pointer syntax the 6472 04:33:51,680 --> 04:33:53,080 reference 6473 04:33:53,080 --> 04:33:56,160 syntax the value is going to be the 6474 04:33:56,160 --> 04:33:58,320 address of 6475 04:33:58,320 --> 04:34:00,520 X so we're going to 6476 04:34:00,520 --> 04:34:03,680 store 169 which is the again the address 6477 04:34:03,680 --> 04:34:07,799 of X as the value and Z is going to be a 6478 04:34:07,799 --> 04:34:10,760 pointer type so kind of the way the go 6479 04:34:10,760 --> 04:34:12,160 programming language works works is it 6480 04:34:12,160 --> 04:34:15,680 knows that Z is effectively pointing to 6481 04:34:15,680 --> 04:34:17,799 the value five right because its address 6482 04:34:17,799 --> 04:34:18,719 is 6483 04:34:18,719 --> 04:34:22,359 171 which stores a pointer to 169 so we 6484 04:34:22,359 --> 04:34:25,600 can look up the value five at address 6485 04:34:25,600 --> 04:34:29,279 169 so what this means is if we update 6486 04:34:29,279 --> 04:34:32,279 the value that Z points to under the 6487 04:34:32,279 --> 04:34:35,561 hood we're updating X so we can do 6488 04:34:35,561 --> 04:34:38,439 things like pass pointers into functions 6489 04:34:38,439 --> 04:34:41,240 change the underlying value and the 6490 04:34:41,240 --> 04:34:43,639 value outside of that function is also 6491 04:34:43,639 --> 04:34:45,561 changed which again in a language like 6492 04:34:45,561 --> 04:34:47,320 go doesn't happen normally because 6493 04:34:47,320 --> 04:34:49,680 typically if you pass a variable like X 6494 04:34:49,680 --> 04:34:52,199 into a function and then change it those 6495 04:34:52,199 --> 04:34:54,639 changes are not seen outside of the 6496 04:34:54,639 --> 04:34:56,439 function you would need to return the 6497 04:34:56,439 --> 04:34:57,959 updated value and then assign it into a 6498 04:34:57,959 --> 04:35:00,240 new variable so pointers basically allow 6499 04:35:00,240 --> 04:35:02,959 us to change the value of something from 6500 04:35:02,959 --> 04:35:04,600 within a function right from within a 6501 04:35:04,600 --> 04:35:07,080 different scope let me show you what 6502 04:35:07,080 --> 04:35:09,039 that looks like in a quick example so 6503 04:35:09,039 --> 04:35:12,879 remember that Z stores the value 6504 04:35:12,879 --> 04:35:15,680 169 which points to this 6505 04:35:15,680 --> 04:35:18,240 address which stores the value 6506 04:35:18,240 --> 04:35:21,680 five so if we want to update the value 6507 04:35:21,680 --> 04:35:24,119 of x without having access to the 6508 04:35:24,119 --> 04:35:27,240 original variable x what we can do is 6509 04:35:27,240 --> 04:35:29,561 use the dfference operator which is an 6510 04:35:29,561 --> 04:35:33,240 asterisk we can dreference Z now this 6511 04:35:33,240 --> 04:35:35,359 dfference operator essentially follows 6512 04:35:35,359 --> 04:35:37,840 this chain and finds the value right and 6513 04:35:37,840 --> 04:35:41,119 we reassign into it let's say the value 6514 04:35:41,119 --> 04:35:45,080 six so this becomes six and this 6515 04:35:45,080 --> 04:35:47,639 location and memory is updated now to 6516 04:35:47,639 --> 04:35:51,160 hold the value six so we've updated the 6517 04:35:51,160 --> 04:35:54,799 value of x without even without even 6518 04:35:54,799 --> 04:35:58,080 using right the name X so now that we've 6519 04:35:58,080 --> 04:36:00,039 kind of covered what a pointer is let's 6520 04:36:00,039 --> 04:36:01,840 look at just a little bit more of the 6521 04:36:01,840 --> 04:36:06,600 syntax in code so the type of a pointer 6522 04:36:06,600 --> 04:36:09,160 is not the type of the underlying value 6523 04:36:09,160 --> 04:36:11,600 alone so if I want a pointer to an 6524 04:36:11,600 --> 04:36:14,000 integer um I actually have to use this 6525 04:36:14,000 --> 04:36:16,039 syntax here I'm creating a new variable 6526 04:36:16,039 --> 04:36:19,279 called p and it's being initialized as a 6527 04:36:19,279 --> 04:36:22,199 pointer to an integer so a pointer is a 6528 04:36:22,199 --> 04:36:26,439 specific type in go now to be fair um 6529 04:36:26,439 --> 04:36:27,879 it's not super common that you're 6530 04:36:27,879 --> 04:36:30,240 creating blank pointers and the zero 6531 04:36:30,240 --> 04:36:33,959 value for a pointer is nil um more often 6532 04:36:33,959 --> 04:36:35,719 than not what you're going to do is have 6533 04:36:35,719 --> 04:36:38,600 a concrete value like this my string 6534 04:36:38,600 --> 04:36:41,080 hello and then you'll create a pointer 6535 04:36:41,080 --> 04:36:44,400 to that value by using the Ampersand 6536 04:36:44,400 --> 04:36:47,520 like we talked about so in this case the 6537 04:36:47,520 --> 04:36:51,240 type of my string is string and the type 6538 04:36:51,240 --> 04:36:54,160 of my string pointer is a pointer to a 6539 04:36:54,160 --> 04:36:57,561 string which would be syntactically star 6540 04:36:57,561 --> 04:37:00,480 string there kind of two primary reasons 6541 04:37:00,480 --> 04:37:02,840 that you would use a pointer in the go 6542 04:37:02,840 --> 04:37:04,879 programming language the first is the 6543 04:37:04,879 --> 04:37:06,760 more common reason which is you want to 6544 04:37:06,760 --> 04:37:09,400 be able to pass a value into a function 6545 04:37:09,400 --> 04:37:11,719 and change the value and have those 6546 04:37:11,719 --> 04:37:13,920 changes kind of persist outside of the 6547 04:37:13,920 --> 04:37:15,480 function right because normally when you 6548 04:37:15,480 --> 04:37:18,719 pass a value into a function a copy is 6549 04:37:18,719 --> 04:37:20,240 passed in so if you want to pass in sort 6550 04:37:20,240 --> 04:37:21,840 of the original value so it can be 6551 04:37:21,840 --> 04:37:24,240 changed and updated uh you might use a 6552 04:37:24,240 --> 04:37:26,600 pointer the second reason is if you're 6553 04:37:26,600 --> 04:37:28,439 very concerned about the performance of 6554 04:37:28,439 --> 04:37:31,039 your program every time you create a 6555 04:37:31,039 --> 04:37:34,000 copy of a variable in memory you have to 6556 04:37:34,000 --> 04:37:36,240 copy that variable in memory right which 6557 04:37:36,240 --> 04:37:39,199 takes some time so if you're dealing 6558 04:37:39,199 --> 04:37:40,799 with lots and lots of data and you're 6559 04:37:40,799 --> 04:37:42,959 trying to be very performant you can 6560 04:37:42,959 --> 04:37:45,439 make micro optimizations and kind of use 6561 04:37:45,439 --> 04:37:47,959 pointers under the hood if you want to 6562 04:37:47,959 --> 04:37:50,680 avoid all of that memory copying now I 6563 04:37:50,680 --> 04:37:52,561 will say that you usually won't want to 6564 04:37:52,561 --> 04:37:54,840 do this upfront because pointers are 6565 04:37:54,840 --> 04:37:57,840 dangerous and they can lead to bugs if 6566 04:37:57,840 --> 04:38:00,160 not used properly so generally speaking 6567 04:38:00,160 --> 04:38:02,400 I would recommend against making those 6568 04:38:02,400 --> 04:38:04,160 performance optimizations unless you 6569 04:38:04,160 --> 04:38:06,199 really need them let's jump into the 6570 04:38:06,199 --> 04:38:08,439 assignment says fix the bug in the send 6571 04:38:08,439 --> 04:38:10,320 message function it's supposed to print 6572 04:38:10,320 --> 04:38:11,840 a nicely formatted message to the 6573 04:38:11,840 --> 04:38:14,359 console containing an sms's uh recipient 6574 04:38:14,359 --> 04:38:15,799 and message body however it's not 6575 04:38:15,799 --> 04:38:18,000 working as expected okay so let's run 6576 04:38:18,000 --> 04:38:20,160 the 6577 04:38:20,160 --> 04:38:23,359 code and we get these kind of weird 6578 04:38:23,359 --> 04:38:25,840 weird looking values that are getting 6579 04:38:25,840 --> 04:38:29,359 printed here in the two and the message 6580 04:38:29,359 --> 04:38:32,840 Fields now this is heximal it's not 6581 04:38:32,840 --> 04:38:36,039 binary it's not decimal it's hexadecimal 6582 04:38:36,039 --> 04:38:38,520 and this is the default formatting for a 6583 04:38:38,520 --> 04:38:41,480 memory address so we have these amp 6584 04:38:41,480 --> 04:38:44,799 perents here they're creating pointers 6585 04:38:44,799 --> 04:38:48,320 to the underlying values that's not what 6586 04:38:48,320 --> 04:38:50,240 we want it's not what we want here right 6587 04:38:50,240 --> 04:38:52,320 that's why this looks disgusting uh we 6588 04:38:52,320 --> 04:38:55,000 need to dreference or or sorry we need 6589 04:38:55,000 --> 04:38:57,400 to remove the reference so I guess D 6590 04:38:57,400 --> 04:38:59,039 reference 6591 04:38:59,039 --> 04:39:01,520 um we need to remove the amperian so 6592 04:39:01,520 --> 04:39:03,359 that we are no longer creating pointers 6593 04:39:03,359 --> 04:39:07,240 so run it again and we get the values 6594 04:39:07,240 --> 04:39:09,561 themselves which is what what we've been 6595 04:39:09,561 --> 04:39:12,520 asked to do 6596 04:39:12,520 --> 04:39:14,799 let's recap some syntax sometimes it can 6597 04:39:14,799 --> 04:39:16,240 get a little confusing between the 6598 04:39:16,240 --> 04:39:18,439 asterisk and the Ampersand what each of 6599 04:39:18,439 --> 04:39:20,760 them mean and in what context so when 6600 04:39:20,760 --> 04:39:23,240 we're talking about the type of a 6601 04:39:23,240 --> 04:39:29,039 variable in go a Pointer's type is star 6602 04:39:29,039 --> 04:39:30,639 and then you know the type of the 6603 04:39:30,639 --> 04:39:32,480 underlying value so a pointer to an INT 6604 04:39:32,480 --> 04:39:36,680 is star int an ampersand is used to 6605 04:39:36,680 --> 04:39:38,920 reference a value so if we want to 6606 04:39:38,920 --> 04:39:43,040 create a pointer to the my string 6607 04:39:43,040 --> 04:39:45,798 variable or the my string value then we 6608 04:39:45,798 --> 04:39:48,878 use an ampersand so the Ampersand 6609 04:39:48,878 --> 04:39:51,440 followed by the name of a variable 6610 04:39:51,440 --> 04:39:54,840 creates a pointer to that variable now 6611 04:39:54,840 --> 04:39:56,160 here's where it can get just a little 6612 04:39:56,160 --> 04:40:00,440 bit tricky the asterisk is again used to 6613 04:40:00,440 --> 04:40:03,440 dreference a pointer so the asterisk is 6614 04:40:03,440 --> 04:40:07,360 used in a Pointer's type it's also used 6615 04:40:07,360 --> 04:40:10,600 as an operator to dreference a pointer 6616 04:40:10,600 --> 04:40:14,360 so when we say say asterisk my string 6617 04:40:14,360 --> 04:40:17,798 pointer this refers to the underlying 6618 04:40:17,798 --> 04:40:19,798 value so we can actually change the 6619 04:40:19,798 --> 04:40:22,638 underlying value Say by assigning it to 6620 04:40:22,638 --> 04:40:25,920 in this case a new string so in short 6621 04:40:25,920 --> 04:40:28,958 ampersands to create new references or 6622 04:40:28,958 --> 04:40:31,840 new pointers to a value and the asterisk 6623 04:40:31,840 --> 04:40:35,080 is used to dreference a pointer and get 6624 04:40:35,080 --> 04:40:37,958 back at that underlying value let's hop 6625 04:40:37,958 --> 04:40:40,120 into the assignment it says complete the 6626 04:40:40,120 --> 04:40:42,480 remove profanity function it should use 6627 04:40:42,480 --> 04:40:44,920 the strings. replace all function so 6628 04:40:44,920 --> 04:40:47,280 this is a a built-in uh function in the 6629 04:40:47,280 --> 04:40:49,360 standard library in the strings package 6630 04:40:49,360 --> 04:40:51,200 uh to replace all instances of the 6631 04:40:51,200 --> 04:40:54,280 following words in the input message 6632 04:40:54,280 --> 04:40:57,400 with asterisks it should mutate the 6633 04:40:57,400 --> 04:40:59,080 value in the pointer and return nothing 6634 04:40:59,080 --> 04:41:01,040 do not alter the function signature Okay 6635 04:41:01,040 --> 04:41:04,400 cool so remove profanity takes as input 6636 04:41:04,400 --> 04:41:08,240 a a a a message variable which is a 6637 04:41:08,240 --> 04:41:10,920 pointer to a string so because it's a 6638 04:41:10,920 --> 04:41:13,440 pointer we're going to be able to mutate 6639 04:41:13,440 --> 04:41:17,280 it without returning anything explicitly 6640 04:41:17,280 --> 04:41:19,480 okay let's jump into it so first thing 6641 04:41:19,480 --> 04:41:22,120 we're going to do is dreference 6642 04:41:22,120 --> 04:41:26,680 the message pointer and store its value 6643 04:41:26,680 --> 04:41:29,440 in a new variable called message value 6644 04:41:29,440 --> 04:41:31,760 and then we'll just update 6645 04:41:31,760 --> 04:41:34,920 this um by using that strings. replace 6646 04:41:34,920 --> 04:41:38,480 all functions strings. replace 6647 04:41:38,480 --> 04:41:41,360 all we want to replace the values in 6648 04:41:41,360 --> 04:41:44,200 message value we want to or I should say 6649 04:41:44,200 --> 04:41:46,080 we want to replace subrings from message 6650 04:41:46,080 --> 04:41:49,280 value uh we'll look for the word dang 6651 04:41:49,280 --> 04:41:52,718 and we'll replace it with four 6652 04:41:53,160 --> 04:41:55,440 asterisks and we want to do the same 6653 04:41:55,440 --> 04:41:58,920 thing twice more with shoot which has 6654 04:41:58,920 --> 04:42:01,440 five letters so let's add an asterisk 6655 04:42:01,440 --> 04:42:04,200 and heck which has four so that should 6656 04:42:04,200 --> 04:42:07,560 be good cool let's let's run this I need 6657 04:42:07,560 --> 04:42:09,080 to import the strings package before I 6658 04:42:09,080 --> 04:42:11,878 forget and see what happens 6659 04:42:11,878 --> 04:42:15,360 so in its current state we actually did 6660 04:42:15,360 --> 04:42:17,560 not update anything right shoot is still 6661 04:42:17,560 --> 04:42:19,638 there dang is still there that's because 6662 04:42:19,638 --> 04:42:21,320 we actually need 6663 04:42:21,320 --> 04:42:24,280 to point the 6664 04:42:24,280 --> 04:42:27,958 message pointer to a string back at the 6665 04:42:27,958 --> 04:42:31,480 updated value so we can do dereferenced 6666 04:42:31,480 --> 04:42:32,920 message 6667 04:42:32,920 --> 04:42:37,520 equals message value let's run 6668 04:42:37,520 --> 04:42:42,400 that perfect let's submit it 6669 04:42:42,400 --> 04:42:44,520 now we've got a pointer quiz so the 6670 04:42:44,520 --> 04:42:47,240 question is what is the value of 6671 04:42:47,240 --> 04:42:50,000 Ampersand y after the code on the left 6672 04:42:50,000 --> 04:42:54,718 executes so we've got X set to 50 Y is a 6673 04:42:54,718 --> 04:42:56,280 pointer to an 6674 04:42:56,280 --> 04:42:58,840 integer okay well in this case it's just 6675 04:42:58,840 --> 04:43:00,798 going to be 100 because we're explicitly 6676 04:43:00,798 --> 04:43:02,440 setting it to 100 on the last line of 6677 04:43:02,440 --> 04:43:05,360 the code so that one was pretty easy now 6678 04:43:05,360 --> 04:43:07,200 this question is a little trickier says 6679 04:43:07,200 --> 04:43:09,920 what is the value of x after the code on 6680 04:43:09,920 --> 04:43:11,878 the left executes 6681 04:43:11,878 --> 04:43:13,718 well X is set to 6682 04:43:13,718 --> 04:43:17,840 50 Y is a pointer to X and then we 6683 04:43:17,840 --> 04:43:21,400 dreference y instead of equal to 100 so 6684 04:43:21,400 --> 04:43:24,718 that's actually also going to be 100 6685 04:43:24,718 --> 04:43:28,280 because we're setting X through Y which 6686 04:43:28,280 --> 04:43:31,160 is a pointer to X I mentioned earlier 6687 04:43:31,160 --> 04:43:33,638 that pointers can be dangerous and that 6688 04:43:33,638 --> 04:43:36,120 is definitely the case um if a pointer 6689 04:43:36,120 --> 04:43:40,400 points to nothing then its zero value is 6690 04:43:40,400 --> 04:43:42,320 nil right so this is the same for 6691 04:43:42,320 --> 04:43:45,798 interfaces or errors right in go fairly 6692 04:43:45,798 --> 04:43:48,840 often you'll be checking at runtime if a 6693 04:43:48,840 --> 04:43:51,798 value is nil or not and the thing about 6694 04:43:51,798 --> 04:43:53,320 pointers is if you ever try to 6695 04:43:53,320 --> 04:43:56,680 dreference a pointer that doesn't point 6696 04:43:56,680 --> 04:43:59,760 to anything your code will Panic so 6697 04:43:59,760 --> 04:44:01,440 pretty much any time you dreference 6698 04:44:01,440 --> 04:44:03,560 something you should be checking before 6699 04:44:03,560 --> 04:44:05,878 you dreference it to make sure that the 6700 04:44:05,878 --> 04:44:08,160 pointer actually points to a valid 6701 04:44:08,160 --> 04:44:10,080 location in memory so this assignment 6702 04:44:10,080 --> 04:44:11,400 says let's make our Prof profanity 6703 04:44:11,400 --> 04:44:13,798 Checker safe update the remove profanity 6704 04:44:13,798 --> 04:44:15,680 function If the message is nil return 6705 04:44:15,680 --> 04:44:17,480 early to avoid a panic okay so let me 6706 04:44:17,480 --> 04:44:20,120 run it in its current state and you'll 6707 04:44:20,120 --> 04:44:22,680 see we get this nasty Panic here it says 6708 04:44:22,680 --> 04:44:25,480 invalid memory address or 6709 04:44:25,480 --> 04:44:29,480 nil okay so what we need to do here is 6710 04:44:29,480 --> 04:44:30,600 if 6711 04:44:30,600 --> 04:44:33,120 message equals equals 6712 04:44:33,120 --> 04:44:37,600 nil return nothing right if we've been 6713 04:44:37,600 --> 04:44:39,798 given an invalid input we'll just bail 6714 04:44:39,798 --> 04:44:42,480 early um another way to do this um if 6715 04:44:42,480 --> 04:44:44,560 the assignment expected something 6716 04:44:44,560 --> 04:44:46,840 different we could return an error here 6717 04:44:46,840 --> 04:44:48,560 right we might do something like return 6718 04:44:48,560 --> 04:44:51,840 errors. new uh invalid input I think 6719 04:44:51,840 --> 04:44:53,400 that would also be a good way to write 6720 04:44:53,400 --> 04:44:55,440 this function uh but we've been asked to 6721 04:44:55,440 --> 04:44:57,480 just do a naked return so we will do 6722 04:44:57,480 --> 04:45:01,000 that let's submit it so let's talk about 6723 04:45:01,000 --> 04:45:03,760 how pointers are used in conjunction 6724 04:45:03,760 --> 04:45:07,200 with methods so you'll very frequently 6725 04:45:07,200 --> 04:45:10,638 see that methods actually take a pointer 6726 04:45:10,638 --> 04:45:11,798 receip 6727 04:45:11,798 --> 04:45:14,920 rather than a non-pointer receiver and 6728 04:45:14,920 --> 04:45:17,320 typically that's done because the method 6729 04:45:17,320 --> 04:45:20,200 will be making changes to the instance 6730 04:45:20,200 --> 04:45:22,520 of the type itself in this case a struct 6731 04:45:22,520 --> 04:45:24,280 right so we have this car with a color 6732 04:45:24,280 --> 04:45:26,798 field and the set color method on the 6733 04:45:26,798 --> 04:45:29,840 car is going to change the color right 6734 04:45:29,840 --> 04:45:32,000 and so here if we create a new car we 6735 04:45:32,000 --> 04:45:34,280 set the color to blue and then print it 6736 04:45:34,280 --> 04:45:36,120 you can see it's been updated to Blue 6737 04:45:36,120 --> 04:45:38,958 instead of white now contrast that with 6738 04:45:38,958 --> 04:45:42,080 a non-pointer receiver 6739 04:45:42,080 --> 04:45:43,798 this acts like a normal function right 6740 04:45:43,798 --> 04:45:45,400 we don't have a pointer so we don't have 6741 04:45:45,400 --> 04:45:47,958 a reference to the location in memory so 6742 04:45:47,958 --> 04:45:50,920 if we update the cars color to Blue it 6743 04:45:50,920 --> 04:45:53,440 actually just stays white it doesn't 6744 04:45:53,440 --> 04:45:56,360 persist that change so that's why I say 6745 04:45:56,360 --> 04:45:58,718 that it's uh more common that you'll see 6746 04:45:58,718 --> 04:46:01,360 pointer receivers on methods than 6747 04:46:01,360 --> 04:46:03,200 non-pointer receivers but but you will 6748 04:46:03,200 --> 04:46:05,120 definitely see both so uh the question 6749 04:46:05,120 --> 04:46:07,320 is which is more widely used in go and 6750 04:46:07,320 --> 04:46:10,000 the answer is pointer receivers now when 6751 04:46:10,000 --> 04:46:12,080 it comes to pointer to receivers one 6752 04:46:12,080 --> 04:46:13,280 thing that's important to understand 6753 04:46:13,280 --> 04:46:15,440 from like a syntactic point of view is 6754 04:46:15,440 --> 04:46:19,240 that even though the uh the input on the 6755 04:46:19,240 --> 04:46:21,120 left hand side right the receiver is a 6756 04:46:21,120 --> 04:46:23,600 pointer when you actually call the 6757 04:46:23,600 --> 04:46:27,000 method you can call in this case right 6758 04:46:27,000 --> 04:46:29,040 the grow method you can actually call it 6759 04:46:29,040 --> 04:46:31,680 on just a normal value or a pointer it 6760 04:46:31,680 --> 04:46:33,920 will sort of cast the value under the 6761 04:46:33,920 --> 04:46:35,558 hood to a pointer if it isn't one 6762 04:46:35,558 --> 04:46:38,558 already right so C in this case is just 6763 04:46:38,558 --> 04:46:41,558 a circle it's not a pointer to a circle 6764 04:46:41,558 --> 04:46:44,680 but when we call c. grow the pointer to 6765 04:46:44,680 --> 04:46:46,878 the circle is passed into the method so 6766 04:46:46,878 --> 04:46:49,120 we didn't need to kind of explicitly you 6767 04:46:49,120 --> 04:46:51,520 know cast c to a pointer to a circle by 6768 04:46:51,520 --> 04:46:54,520 you know adding an Amper sand right here 6769 04:46:54,520 --> 04:46:56,680 okay so with that understood um let's 6770 04:46:56,680 --> 04:46:58,320 move on to the assignment so the 6771 04:46:58,320 --> 04:46:59,798 assignment says fix the bug and the 6772 04:46:59,798 --> 04:47:01,638 codes that set message sets the message 6773 04:47:01,638 --> 04:47:03,600 field of the given email structure and 6774 04:47:03,600 --> 04:47:05,040 the new value persists outside the scope 6775 04:47:05,040 --> 04:47:07,000 of the set message method Okay so we've 6776 04:47:07,000 --> 04:47:09,638 got this email struct we've got the set 6777 04:47:09,638 --> 04:47:11,600 message uh 6778 04:47:11,600 --> 04:47:15,080 the set message method if I run the code 6779 04:47:15,080 --> 04:47:17,320 in its current 6780 04:47:17,320 --> 04:47:20,600 state we've got before message this my 6781 04:47:20,600 --> 04:47:24,440 first draft Sandra Bullock after looks 6782 04:47:24,440 --> 04:47:26,320 identical right and if we go and take a 6783 04:47:26,320 --> 04:47:29,798 look at the test Suite then we can 6784 04:47:29,798 --> 04:47:31,360 see 6785 04:47:31,360 --> 04:47:34,680 that set message is being called this is 6786 04:47:34,680 --> 04:47:37,160 my second draft so we would have 6787 04:47:37,160 --> 04:47:39,520 expected this message to say this is my 6788 04:47:39,520 --> 04:47:40,958 second draft instead of this is my my 6789 04:47:40,958 --> 04:47:42,240 first draft the reason it's not 6790 04:47:42,240 --> 04:47:45,240 happening is because this function 6791 04:47:45,240 --> 04:47:46,558 essentially doesn't do anything this 6792 04:47:46,558 --> 04:47:50,160 method does nothing because this is not 6793 04:47:50,160 --> 04:47:52,480 a pointer to an email let's go ahead and 6794 04:47:52,480 --> 04:47:54,840 run that 6795 04:47:55,200 --> 04:47:59,638 again first draft second draft perfect 6796 04:47:59,638 --> 04:48:00,878 let's submit 6797 04:48:00,878 --> 04:48:03,440 that everything we've done up to this 6798 04:48:03,440 --> 04:48:05,440 point in the course has been in the 6799 04:48:05,440 --> 04:48:07,798 browser we've been writing code right in 6800 04:48:07,798 --> 04:48:10,840 our text editor on boot Dev now we're 6801 04:48:10,840 --> 04:48:12,798 going to break out of that environment 6802 04:48:12,798 --> 04:48:14,920 and do some local development on our own 6803 04:48:14,920 --> 04:48:16,280 machine we're going to figure out how to 6804 04:48:16,280 --> 04:48:19,080 use the go tool chain to build real 6805 04:48:19,080 --> 04:48:20,878 production go 6806 04:48:20,878 --> 04:48:23,600 programs but before we do that let's 6807 04:48:23,600 --> 04:48:26,160 talk a little bit about packages we need 6808 04:48:26,160 --> 04:48:28,360 to understand packages in order to build 6809 04:48:28,360 --> 04:48:30,840 our own go programs now you've probably 6810 04:48:30,840 --> 04:48:32,400 noticed that up until this point in the 6811 04:48:32,400 --> 04:48:34,440 course every coding assignment has had 6812 04:48:34,440 --> 04:48:37,400 the words package main at the top of the 6813 04:48:37,400 --> 04:48:39,040 file that just means that we've been 6814 04:48:39,040 --> 04:48:41,400 writing code within the main 6815 04:48:41,400 --> 04:48:43,320 package and that's actually really 6816 04:48:43,320 --> 04:48:46,638 important the main package is a special 6817 04:48:46,638 --> 04:48:49,320 type of package it's a package that runs 6818 04:48:49,320 --> 04:48:52,280 as a standalone program so anytime 6819 04:48:52,280 --> 04:48:54,520 you're writing an actual application 6820 04:48:54,520 --> 04:48:56,320 that you need to run say on the command 6821 04:48:56,320 --> 04:48:58,360 line or as a server you'll be writing 6822 04:48:58,360 --> 04:49:01,558 code within the main package a package 6823 04:49:01,558 --> 04:49:05,280 with any other name so any name besides 6824 04:49:05,280 --> 04:49:08,840 main is a library package and basically 6825 04:49:08,840 --> 04:49:11,280 what that means is it's imported by 6826 04:49:11,280 --> 04:49:14,680 other libraries and application code so 6827 04:49:14,680 --> 04:49:16,798 some oftentimes it's just imported by a 6828 04:49:16,798 --> 04:49:19,320 main package so that it can use it if 6829 04:49:19,320 --> 04:49:21,878 you're familiar with npm from JavaScript 6830 04:49:21,878 --> 04:49:24,600 or pip from python that's effectively 6831 04:49:24,600 --> 04:49:27,280 what a non-main package is in go it's 6832 04:49:27,280 --> 04:49:29,520 just some code that you can publish as 6833 04:49:29,520 --> 04:49:31,920 kind of a standalone library that then 6834 04:49:31,920 --> 04:49:35,200 other developers can use in their main 6835 04:49:35,200 --> 04:49:38,160 packages in their actual applications so 6836 04:49:38,160 --> 04:49:40,718 let's take a look at an example here so 6837 04:49:40,718 --> 04:49:42,440 you're probably familiar with this style 6838 04:49:42,440 --> 04:49:44,440 of code it's what we've been writing uh 6839 04:49:44,440 --> 04:49:46,280 all throughout this course we've been 6840 04:49:46,280 --> 04:49:48,000 writing within the main package because 6841 04:49:48,000 --> 04:49:50,558 we've been writing executable scripts 6842 04:49:50,558 --> 04:49:53,240 right code that actually runs and does 6843 04:49:53,240 --> 04:49:55,760 something and then we have this import 6844 04:49:55,760 --> 04:49:57,480 statement where we've typically just 6845 04:49:57,480 --> 04:49:59,200 been importing from the standard library 6846 04:49:59,200 --> 04:50:02,400 but the standard library is made up of 6847 04:50:02,400 --> 04:50:04,958 Library packages right like the fmt 6848 04:50:04,958 --> 04:50:08,600 package or the math SL random package 6849 04:50:08,600 --> 04:50:10,080 the interesting thing about the main 6850 04:50:10,080 --> 04:50:13,000 package is it always has a main function 6851 04:50:13,000 --> 04:50:15,000 and that main function serves as the 6852 04:50:15,000 --> 04:50:17,680 entry point to the program so packages 6853 04:50:17,680 --> 04:50:20,680 that are not main packages their Library 6854 04:50:20,680 --> 04:50:23,280 packages will just export functions 6855 04:50:23,280 --> 04:50:26,040 named functions to be used Again by 6856 04:50:26,040 --> 04:50:28,878 other libraries and application code 6857 04:50:28,878 --> 04:50:31,558 only main packages will have a main 6858 04:50:31,558 --> 04:50:33,360 function that runs when the program 6859 04:50:33,360 --> 04:50:35,320 starts so to jump into the coding 6860 04:50:35,320 --> 04:50:37,120 assignment it just says fix the bug in 6861 04:50:37,120 --> 04:50:38,440 the code so let's go ahead and run the 6862 04:50:38,440 --> 04:50:42,600 code and see what happens 6863 04:50:46,798 --> 04:50:49,360 nothing happens right we're stuck in 6864 04:50:49,360 --> 04:50:52,240 this infinite Loop apparently apparently 6865 04:50:52,240 --> 04:50:55,400 this code compiles and then does nothing 6866 04:50:55,400 --> 04:50:58,400 it's kind of a weird Behavior right um 6867 04:50:58,400 --> 04:51:01,000 in order to fix this all we need to do 6868 04:51:01,000 --> 04:51:02,240 is update 6869 04:51:02,240 --> 04:51:05,320 this to be a main package so that we get 6870 04:51:05,320 --> 04:51:08,200 as output for our code a runnable 6871 04:51:08,200 --> 04:51:09,840 executable a script that we can actually 6872 04:51:09,840 --> 04:51:11,080 execute in the browser so let's go ahead 6873 04:51:11,080 --> 04:51:14,080 and run that and we get starting maleo 6874 04:51:14,080 --> 04:51:16,760 server stopping maleo server kind of as 6875 04:51:16,760 --> 04:51:20,360 we would expect uh based on uh based on 6876 04:51:20,360 --> 04:51:21,558 this code here so I'm going to go ahead 6877 04:51:21,558 --> 04:51:23,958 and submit that so we're familiar with 6878 04:51:23,958 --> 04:51:25,958 main packages but what about Library 6879 04:51:25,958 --> 04:51:29,120 packages well by convention a package's 6880 04:51:29,120 --> 04:51:31,798 name is the same as the last element of 6881 04:51:31,798 --> 04:51:33,878 its import path so for example the math 6882 04:51:33,878 --> 04:51:37,360 Rand or math SL Rand package from the 6883 04:51:37,360 --> 04:51:40,638 ghost standard Library um has files that 6884 04:51:40,638 --> 04:51:43,878 begin with package Rand so the Rand 6885 04:51:43,878 --> 04:51:47,360 package lives at math SL Rand now it's 6886 04:51:47,360 --> 04:51:48,798 important to point out that the standard 6887 04:51:48,798 --> 04:51:50,680 Library actually has another Rand 6888 04:51:50,680 --> 04:51:54,160 package at crypto Rand so they're both 6889 04:51:54,160 --> 04:51:55,958 kind of the Rand package but they have 6890 04:51:55,958 --> 04:51:59,200 different import paths when a package 6891 04:51:59,200 --> 04:52:01,920 isn't part of the standard Library when 6892 04:52:01,920 --> 04:52:04,240 for example you make your own Library 6893 04:52:04,240 --> 04:52:08,080 package the import path is typically the 6894 04:52:08,080 --> 04:52:10,680 same as the remote URL that you you'd 6895 04:52:10,680 --> 04:52:13,000 use to go look at that library's source 6896 04:52:13,000 --> 04:52:16,440 code so for example in our fictitious 6897 04:52:16,440 --> 04:52:19,080 maleo products right part of the textio 6898 04:52:19,080 --> 04:52:22,200 conglomerate of messaging products uh 6899 04:52:22,200 --> 04:52:23,638 they might have their own GitHub 6900 04:52:23,638 --> 04:52:26,798 namespace it's slmo so github.com is 6901 04:52:26,798 --> 04:52:28,760 their GitHub organization and then maybe 6902 04:52:28,760 --> 04:52:30,878 they create their own package or their 6903 04:52:30,878 --> 04:52:33,520 own excuse me repository on GitHub 6904 04:52:33,520 --> 04:52:36,160 called Rand and that's where the 6905 04:52:36,160 --> 04:52:38,280 repository for their Rand package lives 6906 04:52:38,280 --> 04:52:39,760 that's where the source code lives on 6907 04:52:39,760 --> 04:52:42,080 the internet right github.com 6908 04:52:42,080 --> 04:52:44,878 Rand now that package's name by 6909 04:52:44,878 --> 04:52:47,680 convention should be Rand because that's 6910 04:52:47,680 --> 04:52:52,080 the last section of the import path but 6911 04:52:52,080 --> 04:52:53,958 that's just a convention they could if 6912 04:52:53,958 --> 04:52:56,000 they wanted to change the name of the 6913 04:52:56,000 --> 04:52:58,240 package to say random and then all of 6914 04:52:58,240 --> 04:53:01,040 the files in their source code would say 6915 04:53:01,040 --> 04:53:04,200 package random now again it is possible 6916 04:53:04,200 --> 04:53:06,878 to use a different package name one 6917 04:53:06,878 --> 04:53:09,040 that's not the same as the last section 6918 04:53:09,040 --> 04:53:11,040 of the import path but I highly 6919 04:53:11,040 --> 04:53:13,680 discourage it um it is best practice to 6920 04:53:13,680 --> 04:53:15,480 just use the convention and keep 6921 04:53:15,480 --> 04:53:17,680 everything consistent now one last thing 6922 04:53:17,680 --> 04:53:20,520 to point out here is that in go packages 6923 04:53:20,520 --> 04:53:23,280 live at the directory level rather than 6924 04:53:23,280 --> 04:53:26,120 the file level so if you're used to say 6925 04:53:26,120 --> 04:53:28,920 python or JavaScript you might be used 6926 04:53:28,920 --> 04:53:31,160 to importing code directly from other 6927 04:53:31,160 --> 04:53:35,080 files in go if all of the code lives 6928 04:53:35,080 --> 04:53:37,240 within the same directory then it's part 6929 04:53:37,240 --> 04:53:39,040 of the same package and you don't need 6930 04:53:39,040 --> 04:53:41,878 to Import and Export code between files 6931 04:53:41,878 --> 04:53:43,798 in the same package or in the same 6932 04:53:43,798 --> 04:53:46,798 directory so in go you would only need 6933 04:53:46,798 --> 04:53:48,920 to import code if it lives in a 6934 04:53:48,920 --> 04:53:51,360 different directory or a different 6935 04:53:51,360 --> 04:53:53,638 package and packages and directories are 6936 04:53:53,638 --> 04:53:55,840 one and the same you can't have multiple 6937 04:53:55,840 --> 04:53:58,638 packages in the same directory so the 6938 04:53:58,638 --> 04:54:00,520 quiz question for this section is what 6939 04:54:00,520 --> 04:54:02,600 would be the conventional package name 6940 04:54:02,600 --> 04:54:06,000 of a package with the path github.com 6941 04:54:06,000 --> 04:54:09,878 waglan parser and the answer is going to 6942 04:54:09,878 --> 04:54:12,080 be parer because it should match the 6943 04:54:12,080 --> 04:54:14,840 last section of the import path the next 6944 04:54:14,840 --> 04:54:17,480 question on the topic of package naming 6945 04:54:17,480 --> 04:54:21,718 is given the import path of path to Rand 6946 04:54:21,718 --> 04:54:25,320 path2 Rand which of these is a valid 6947 04:54:25,320 --> 04:54:27,600 package name so notice it's not asking 6948 04:54:27,600 --> 04:54:29,160 which is a conventional it's asking 6949 04:54:29,160 --> 04:54:31,240 which one is actually valid we've got 6950 04:54:31,240 --> 04:54:33,920 random Rand spam any of these path well 6951 04:54:33,920 --> 04:54:36,440 Rand would be the conventional name but 6952 04:54:36,440 --> 04:54:38,878 actually any of these could technically 6953 04:54:38,878 --> 04:54:42,040 be used okay it's time to write some go 6954 04:54:42,040 --> 04:54:43,798 code on our local machines and you're 6955 04:54:43,798 --> 04:54:45,718 going to need three things in order to 6956 04:54:45,718 --> 04:54:47,878 make it through the rest of this chapter 6957 04:54:47,878 --> 04:54:50,040 the first thing is you're going to need 6958 04:54:50,040 --> 04:54:52,760 an editor I'll be using VSS code 6959 04:54:52,760 --> 04:54:54,160 throughout the rest of this chapter to 6960 04:54:54,160 --> 04:54:55,798 do all of our local development stuff 6961 04:54:55,798 --> 04:54:57,600 you can use vs code or you can use 6962 04:54:57,600 --> 04:54:59,520 something else uh that you're more 6963 04:54:59,520 --> 04:55:01,840 familiar with if you do use vs code 6964 04:55:01,840 --> 04:55:03,320 you'll probably want to install the 6965 04:55:03,320 --> 04:55:06,160 official goang plug-in the next thing 6966 04:55:06,160 --> 04:55:09,160 you'll need is a Unix like or sh like 6967 04:55:09,160 --> 04:55:11,600 terminal so if you're on Mac or Linux 6968 04:55:11,600 --> 04:55:13,240 then the built-in terminal will work 6969 04:55:13,240 --> 04:55:15,558 just fine if you're on Windows you have 6970 04:55:15,558 --> 04:55:17,400 a few different options personally I 6971 04:55:17,400 --> 04:55:19,718 would recommend installing Ubuntu in 6972 04:55:19,718 --> 04:55:22,240 wsl2 I'll link uh in the description 6973 04:55:22,240 --> 04:55:24,360 down below how to do that uh but you 6974 04:55:24,360 --> 04:55:26,440 will need to have a terminal in order to 6975 04:55:26,440 --> 04:55:28,440 follow along with these instructions if 6976 04:55:28,440 --> 04:55:29,840 you choose to use something like the 6977 04:55:29,840 --> 04:55:31,280 default Windows command line you're 6978 04:55:31,280 --> 04:55:32,718 going to have to change some of the 6979 04:55:32,718 --> 04:55:34,600 instructions in the terminal uh to kind 6980 04:55:34,600 --> 04:55:36,760 of translate them to your own machine 6981 04:55:36,760 --> 04:55:38,200 the last thing you'll need is just to 6982 04:55:38,200 --> 04:55:40,280 install the go tool chain on your local 6983 04:55:40,280 --> 04:55:42,120 machine and I would recommend one of two 6984 04:55:42,120 --> 04:55:44,400 different ways the first is to use uh 6985 04:55:44,400 --> 04:55:46,440 the official download page and the 6986 04:55:46,440 --> 04:55:49,280 second is to use um the Webby download 6987 04:55:49,280 --> 04:55:51,240 script either of them will work and I've 6988 04:55:51,240 --> 04:55:53,040 linked them both on this page so you can 6989 04:55:53,040 --> 04:55:55,320 go check them out and get go downloaded 6990 04:55:55,320 --> 04:55:57,600 now once you've downloaded and installed 6991 04:55:57,600 --> 04:55:59,280 go the way you can test to make sure 6992 04:55:59,280 --> 04:56:00,958 that everything is working correctly is 6993 04:56:00,958 --> 04:56:04,320 type Go version in your terminal if you 6994 04:56:04,320 --> 04:56:07,360 get back a valid Go version of at least 6995 04:56:07,360 --> 04:56:08,280 version 6996 04:56:08,280 --> 04:56:10,558 1.20 which is what I'm using at the time 6997 04:56:10,558 --> 04:56:12,320 of recording this video uh then you 6998 04:56:12,320 --> 04:56:14,320 should be good to go now I need to point 6999 04:56:14,320 --> 04:56:15,760 out at this point that some people get 7000 04:56:15,760 --> 04:56:18,040 confused and think this is Go version 7001 04:56:18,040 --> 04:56:21,798 1.2 it's not it's Go version 1.20 which 7002 04:56:21,798 --> 04:56:25,200 is the same as Go version 1.20 which is 7003 04:56:25,200 --> 04:56:28,958 one version greater than go 1.19 or go 7004 04:56:28,958 --> 04:56:31,080 1.19 so make sure that you're not on Go 7005 04:56:31,080 --> 04:56:34,160 1.2 that would be very very old if 7006 04:56:34,160 --> 04:56:35,958 you're having trouble getting go 7007 04:56:35,958 --> 04:56:37,638 installed so that you can use it within 7008 04:56:37,638 --> 04:56:39,280 your terminal uh the first thing I'll 7009 04:56:39,280 --> 04:56:41,280 have you do is definitely to try closing 7010 04:56:41,280 --> 04:56:43,878 your shell session and restarting it um 7011 04:56:43,878 --> 04:56:45,360 a lot of times that can help just 7012 04:56:45,360 --> 04:56:48,400 getting go into your path uh if that 7013 04:56:48,400 --> 04:56:51,080 doesn't work then Googling around uh C 7014 04:56:51,080 --> 04:56:53,320 can can be one method to kind of try to 7015 04:56:53,320 --> 04:56:54,400 figure out what's going on on your 7016 04:56:54,400 --> 04:56:55,840 machine it's really hard for me to kind 7017 04:56:55,840 --> 04:56:58,680 of predict what issues you might have 7018 04:56:58,680 --> 04:57:00,638 especially considering the fact that Mac 7019 04:57:00,638 --> 04:57:02,718 OS windows and Linux can all be a little 7020 04:57:02,718 --> 04:57:05,000 different but what I will recommend is 7021 04:57:05,000 --> 04:57:06,958 that if you are having trouble jump into 7022 04:57:06,958 --> 04:57:09,798 the bootd Discord and ask a specific 7023 04:57:09,798 --> 04:57:11,520 question about the trouble you're having 7024 04:57:11,520 --> 04:57:13,558 and we'll be happy to help you out so 7025 04:57:13,558 --> 04:57:15,080 the question for this step really just 7026 04:57:15,080 --> 04:57:16,638 to confirm that we installed go 7027 04:57:16,638 --> 04:57:19,040 correctly and that we can use it uh asks 7028 04:57:19,040 --> 04:57:21,320 what does the Go version command print 7029 04:57:21,320 --> 04:57:23,080 and if we check the output we can see it 7030 04:57:23,080 --> 04:57:26,760 says Go version go 1.20 so that's the 7031 04:57:26,760 --> 04:57:28,638 that's the version of the go tool chain 7032 04:57:28,638 --> 04:57:31,200 we have uh Darwin I'm on a Mac so this 7033 04:57:31,200 --> 04:57:33,798 is like the core Unix operating system 7034 04:57:33,798 --> 04:57:36,360 and then amd64 which is my CPU 7035 04:57:36,360 --> 04:57:38,958 architecture so it's going to be this 7036 04:57:38,958 --> 04:57:41,520 bottom one so we've talked about 7037 04:57:41,520 --> 04:57:42,920 packages and we've talked about how 7038 04:57:42,920 --> 04:57:44,440 packages exist basically at the 7039 04:57:44,440 --> 04:57:47,000 directory level and go now we need to 7040 04:57:47,000 --> 04:57:50,958 talk about modules a module is a bigger 7041 04:57:50,958 --> 04:57:54,000 idea than just a package a module is 7042 04:57:54,000 --> 04:57:57,000 kind of a releasable collection of go 7043 04:57:57,000 --> 04:57:59,160 packages so sometimes it's just a single 7044 04:57:59,160 --> 04:58:00,718 package right you have a single package 7045 04:58:00,718 --> 04:58:03,600 a single module and you release it um as 7046 04:58:03,600 --> 04:58:05,638 one package but other times you might 7047 04:58:05,638 --> 04:58:08,958 break that main package up into sub 7048 04:58:08,958 --> 04:58:11,638 packages and you'd release all of those 7049 04:58:11,638 --> 04:58:15,760 packages together as one go module now a 7050 04:58:15,760 --> 04:58:18,840 repository is not a unique idea to go 7051 04:58:18,840 --> 04:58:21,680 but it's sort of even greater than just 7052 04:58:21,680 --> 04:58:25,680 a module repository or a git repository 7053 04:58:25,680 --> 04:58:27,718 is just a collection of code that you 7054 04:58:27,718 --> 04:58:29,840 kind of keep in Source control all at 7055 04:58:29,840 --> 04:58:32,558 the same level and it can contain one or 7056 04:58:32,558 --> 04:58:34,958 more modules though it's actually really 7057 04:58:34,958 --> 04:58:37,520 common for a single repository to just 7058 04:58:37,520 --> 04:58:40,558 have a single go module with within it 7059 04:58:40,558 --> 04:58:43,760 so while one monor repo can have many 7060 04:58:43,760 --> 04:58:45,680 different go modules inside of it I 7061 04:58:45,680 --> 04:58:47,798 would argue that's not usually the case 7062 04:58:47,798 --> 04:58:50,000 typically you'll have one go module 7063 04:58:50,000 --> 04:58:52,480 living in one repository that's not a 7064 04:58:52,480 --> 04:58:54,200 convention that's just the way I've seen 7065 04:58:54,200 --> 04:58:56,440 it more often than not so for the sake 7066 04:58:56,440 --> 04:58:59,760 of example let's assume a git repository 7067 04:58:59,760 --> 04:59:02,600 that contains a single module and that 7068 04:59:02,600 --> 04:59:03,958 means that at the root of the git 7069 04:59:03,958 --> 04:59:06,440 repository we'd have a single go dood 7070 04:59:06,440 --> 04:59:09,400 file that looks something like this the 7071 04:59:09,400 --> 04:59:12,440 first line contains the path prefix for 7072 04:59:12,440 --> 04:59:14,520 the entire module so remember a module 7073 04:59:14,520 --> 04:59:17,760 can contain multiple packages and every 7074 04:59:17,760 --> 04:59:20,798 package in that module its import path 7075 04:59:20,798 --> 04:59:23,280 is going to be prefixed with the path of 7076 04:59:23,280 --> 04:59:25,320 the entire module uh the next line just 7077 04:59:25,320 --> 04:59:28,040 specifies the Go version um and the last 7078 04:59:28,040 --> 04:59:31,320 line will specify any dependencies that 7079 04:59:31,320 --> 04:59:35,000 this module depends on so to answer the 7080 04:59:35,000 --> 04:59:37,920 question what is a go module an 7081 04:59:37,920 --> 04:59:40,798 executable main package um no that could 7082 04:59:40,798 --> 04:59:43,440 be part of a go module but it's not a go 7083 04:59:43,440 --> 04:59:44,480 module 7084 04:59:44,480 --> 04:59:46,680 itself a collection of packages that are 7085 04:59:46,680 --> 04:59:49,360 released together that is accurate a 7086 04:59:49,360 --> 04:59:52,160 file of go code no a module will contain 7087 04:59:52,160 --> 04:59:55,000 many many files of go code um or a 7088 04:59:55,000 --> 04:59:57,520 library package and again no not 7089 04:59:57,520 --> 04:59:59,080 necessarily you could have a module 7090 04:59:59,080 --> 05:00:01,400 that's just a single Library package but 7091 05:00:01,400 --> 05:00:03,600 a go module can be many more packages 7092 05:00:03,600 --> 05:00:05,280 than that or it could be a main package 7093 05:00:05,280 --> 05:00:06,600 for example so it's going to be a 7094 05:00:06,600 --> 05:00:08,958 collection of packages that are released 7095 05:00:08,958 --> 05:00:11,360 together so we need to talk just a 7096 05:00:11,360 --> 05:00:14,680 little bit more about these import paths 7097 05:00:14,680 --> 05:00:16,798 now if you're familiar with npm from the 7098 05:00:16,798 --> 05:00:19,520 JavaScript e ecosystem uh cargo from the 7099 05:00:19,520 --> 05:00:21,958 rust ecosystem or pip from the python 7100 05:00:21,958 --> 05:00:23,718 ecosystem then you're probably familiar 7101 05:00:23,718 --> 05:00:26,160 with the idea of a namespace for a third 7102 05:00:26,160 --> 05:00:28,680 party package for example I might make a 7103 05:00:28,680 --> 05:00:32,160 package called Left pad publish it up to 7104 05:00:32,160 --> 05:00:35,000 npms uh Central repository and now 7105 05:00:35,000 --> 05:00:36,920 anyone in the world just knowing my kind 7106 05:00:36,920 --> 05:00:39,400 of namespace name uh leftpad can 7107 05:00:39,400 --> 05:00:42,920 download use my code as a dependency the 7108 05:00:42,920 --> 05:00:44,920 interesting thing about the go ecosystem 7109 05:00:44,920 --> 05:00:47,440 is that there is no central location for 7110 05:00:47,440 --> 05:00:51,920 thirdparty packages like npmjs.com in 7111 05:00:51,920 --> 05:00:55,280 JavaScript land instead the gotool chain 7112 05:00:55,280 --> 05:00:58,440 sort of works on top of git and actually 7113 05:00:58,440 --> 05:01:02,200 uses the import path as the remote URL 7114 05:01:02,200 --> 05:01:04,718 and it looks to that import path for 7115 05:01:04,718 --> 05:01:07,320 where it can go download code so more 7116 05:01:07,320 --> 05:01:09,558 often than not you'll see modules with 7117 05:01:09,558 --> 05:01:11,760 import paths that start with github.com 7118 05:01:11,760 --> 05:01:14,558 or gitlab.com because that's where the 7119 05:01:14,558 --> 05:01:17,280 code itself is hosted an important 7120 05:01:17,280 --> 05:01:19,480 exception to this rule that the import 7121 05:01:19,480 --> 05:01:20,798 path is where you go to download the 7122 05:01:20,798 --> 05:01:22,760 code is the standard Library you don't 7123 05:01:22,760 --> 05:01:25,160 need to download standard Library code 7124 05:01:25,160 --> 05:01:28,200 it comes packaged with the go tool chain 7125 05:01:28,200 --> 05:01:29,920 so the question is do packages in the 7126 05:01:29,920 --> 05:01:31,878 standard Library have a module path 7127 05:01:31,878 --> 05:01:34,718 prefix the answer is 7128 05:01:34,718 --> 05:01:37,638 no the next question is what is an 7129 05:01:37,638 --> 05:01:39,000 import path and I know we've already 7130 05:01:39,000 --> 05:01:40,558 talked about this but I to show you a 7131 05:01:40,558 --> 05:01:42,878 more concrete example so this is the 7132 05:01:42,878 --> 05:01:44,280 github.com 7133 05:01:44,280 --> 05:01:48,680 waglan go- rabbitmq GitHub repository so 7134 05:01:48,680 --> 05:01:50,320 this is a GitHub repository that I 7135 05:01:50,320 --> 05:01:52,480 maintain it's just a little package for 7136 05:01:52,480 --> 05:01:55,200 Rabbid mq users a little go client for 7137 05:01:55,200 --> 05:01:58,200 Rabbid mq so this is a library module 7138 05:01:58,200 --> 05:02:00,760 and a library package it's intended for 7139 05:02:00,760 --> 05:02:03,160 other developers to actually import this 7140 05:02:03,160 --> 05:02:05,680 code into their applications it's not a 7141 05:02:05,680 --> 05:02:08,878 standalone you know main package so 7142 05:02:08,878 --> 05:02:12,280 let's take a look at the file structure 7143 05:02:12,280 --> 05:02:13,878 at the very root of the repository we 7144 05:02:13,878 --> 05:02:17,120 have the go dood file now this is that 7145 05:02:17,120 --> 05:02:20,080 kind of simple standard setup where one 7146 05:02:20,080 --> 05:02:22,600 git repository happens to have one go 7147 05:02:22,600 --> 05:02:26,080 modable or one sort of releasable unit 7148 05:02:26,080 --> 05:02:29,958 of code and if we take a peek inside we 7149 05:02:29,958 --> 05:02:33,400 can see that the go dood file uh 7150 05:02:33,400 --> 05:02:37,120 specifies the import path github.com 7151 05:02:37,120 --> 05:02:41,760 waglan go- rabbitmq Q so this matches 7152 05:02:41,760 --> 05:02:45,280 the URL of the git repository hosted on 7153 05:02:45,280 --> 05:02:48,160 GitHub now here's the interesting thing 7154 05:02:48,160 --> 05:02:52,600 this module only has one package that's 7155 05:02:52,600 --> 05:02:54,160 exported to the outside world and it 7156 05:02:54,160 --> 05:02:55,520 exists here at this top level so you can 7157 05:02:55,520 --> 05:02:58,080 see all of these go files consume. Go 7158 05:02:58,080 --> 05:03:00,400 consumer options. go they exist at the 7159 05:03:00,400 --> 05:03:03,320 top level of the repository so when you 7160 05:03:03,320 --> 05:03:06,680 import this package to use it you just 7161 05:03:06,680 --> 05:03:10,120 import from this root path because the 7162 05:03:10,120 --> 05:03:13,080 root package is what you're importing 7163 05:03:13,080 --> 05:03:16,040 there are no sub packages to import here 7164 05:03:16,040 --> 05:03:17,520 but let's pretend for a second that we 7165 05:03:17,520 --> 05:03:20,400 did want to export another package in 7166 05:03:20,400 --> 05:03:23,000 the same go module so we have our top 7167 05:03:23,000 --> 05:03:26,000 level go module G rabbit mq and the top 7168 05:03:26,000 --> 05:03:28,638 level package that can be accessed at 7169 05:03:28,638 --> 05:03:31,798 the same import path as the module let's 7170 05:03:31,798 --> 05:03:34,240 say we added another directory we could 7171 05:03:34,240 --> 05:03:36,718 call it maybe networks and inside it 7172 05:03:36,718 --> 05:03:39,360 would be the networks package if someone 7173 05:03:39,360 --> 05:03:42,160 wanted to import that package then they 7174 05:03:42,160 --> 05:03:44,160 would take the import path for the 7175 05:03:44,160 --> 05:03:46,520 entire module github.com 7176 05:03:46,520 --> 05:03:49,718 waglan rabbitmq which points to the root 7177 05:03:49,718 --> 05:03:51,558 package like we already talked about and 7178 05:03:51,558 --> 05:03:53,520 it would just append another slash 7179 05:03:53,520 --> 05:03:56,160 networks onto the end right so the 7180 05:03:56,160 --> 05:03:59,558 module path serves as a prefix for any 7181 05:03:59,558 --> 05:04:02,680 nested packages so to answer the 7182 05:04:02,680 --> 05:04:05,200 original question what is an import path 7183 05:04:05,200 --> 05:04:07,040 well it's not an HTTP connection and 7184 05:04:07,040 --> 05:04:09,440 it's not a restful server it's a module 7185 05:04:09,440 --> 05:04:10,440 path 7186 05:04:10,440 --> 05:04:14,558 plus an optional package subdirectory so 7187 05:04:14,558 --> 05:04:16,520 we've talked about repositories modules 7188 05:04:16,520 --> 05:04:18,520 packages you've got go installed now 7189 05:04:18,520 --> 05:04:20,240 let's talk about how you can set up your 7190 05:04:20,240 --> 05:04:22,958 local development environment and some 7191 05:04:22,958 --> 05:04:24,240 of this stuff isn't going to be 7192 05:04:24,240 --> 05:04:25,760 necessary and I'll point that out but I 7193 05:04:25,760 --> 05:04:27,520 do want to show you how I've set up my 7194 05:04:27,520 --> 05:04:29,798 machine um and you can emulate the way I 7195 05:04:29,798 --> 05:04:33,000 do it if you like that style now I need 7196 05:04:33,000 --> 05:04:36,400 to mention the go paath if you're 7197 05:04:36,400 --> 05:04:37,840 Googling around trying to figure out how 7198 05:04:37,840 --> 05:04:39,080 to set up your local development 7199 05:04:39,080 --> 05:04:40,798 environment for go you will almost 7200 05:04:40,798 --> 05:04:42,840 certainly come across old outdated 7201 05:04:42,840 --> 05:04:45,440 articles that talk about the go path in 7202 05:04:45,440 --> 05:04:47,480 kind of any version newer than I think 7203 05:04:47,480 --> 05:04:50,400 it's 1.13 right so we're on 7204 05:04:50,400 --> 05:04:53,920 1.20 now um you can basically forget 7205 05:04:53,920 --> 05:04:55,600 about the go path you don't need to 7206 05:04:55,600 --> 05:04:57,840 worry about it um you used to have to 7207 05:04:57,840 --> 05:05:00,638 put your code in the go path um now the 7208 05:05:00,638 --> 05:05:02,520 recommended way is actually to not put 7209 05:05:02,520 --> 05:05:04,958 your code in the go path can be a little 7210 05:05:04,958 --> 05:05:07,280 confusing but again generally speaking 7211 05:05:07,280 --> 05:05:09,440 you can just forget about the go path 7212 05:05:09,440 --> 05:05:11,440 and if you find any articles that talk 7213 05:05:11,440 --> 05:05:14,280 about it they're probably outdated the 7214 05:05:14,280 --> 05:05:17,680 entire idea of go modules is what 7215 05:05:17,680 --> 05:05:20,400 replaced the old go path so the question 7216 05:05:20,400 --> 05:05:22,400 is do you need to put your code inside 7217 05:05:22,400 --> 05:05:25,280 of your go path um the answers are yes 7218 05:05:25,280 --> 05:05:26,638 it doesn't matter and no in fact you 7219 05:05:26,638 --> 05:05:29,360 shouldn't and actually in fact you 7220 05:05:29,360 --> 05:05:30,480 [Music] 7221 05:05:30,480 --> 05:05:32,680 shouldn't so I've altered my window 7222 05:05:32,680 --> 05:05:34,558 layout um so that's a little bit easier 7223 05:05:34,558 --> 05:05:36,360 for you to see what I'm doing I've got 7224 05:05:36,360 --> 05:05:38,040 the boot Dev instructions over here on 7225 05:05:38,040 --> 05:05:40,718 the left and then I've got vs code over 7226 05:05:40,718 --> 05:05:42,600 here on the right with my terminal at 7227 05:05:42,600 --> 05:05:44,480 the bottom cool so I'm just here in my 7228 05:05:44,480 --> 05:05:46,600 file system I'm not within the go path 7229 05:05:46,600 --> 05:05:47,958 I'm just kind of in my personal 7230 05:05:47,958 --> 05:05:50,120 workspace um and we'll just follow these 7231 05:05:50,120 --> 05:05:51,320 instructions it says create a new 7232 05:05:51,320 --> 05:05:53,718 directory and enter it so we'll make 7233 05:05:53,718 --> 05:05:55,920 directory hello 7234 05:05:55,920 --> 05:05:59,320 go and me just LS show you the new 7235 05:05:59,320 --> 05:06:01,320 directory was created and we'll enter 7236 05:06:01,320 --> 05:06:05,000 that directory cool now inside of that 7237 05:06:05,000 --> 05:06:06,920 new hello go directory I'm going to 7238 05:06:06,920 --> 05:06:08,600 create a new go module so we'll do go 7239 05:06:08,600 --> 05:06:10,360 mod in it 7240 05:06:10,360 --> 05:06:12,760 and I keep all of my code on GitHub so 7241 05:06:12,760 --> 05:06:14,920 I'll do github.com 7242 05:06:14,920 --> 05:06:17,558 SL my username because that's my 7243 05:06:17,558 --> 05:06:21,040 namespace on GitHub so Wags Lane slash 7244 05:06:21,040 --> 05:06:23,200 the name of this project which uh we're 7245 05:06:23,200 --> 05:06:26,878 just calling hello go cool says go 7246 05:06:26,878 --> 05:06:29,600 creating new module um now if I LS I 7247 05:06:29,600 --> 05:06:33,718 should see that new go.mod file next 7248 05:06:33,718 --> 05:06:36,200 let's go ahead and take a look at that 7249 05:06:36,200 --> 05:06:38,920 file so you can see it just created a 7250 05:06:38,920 --> 05:06:40,400 new module 7251 05:06:40,400 --> 05:06:43,558 github.com wax laneel go with the Go 7252 05:06:43,558 --> 05:06:45,558 version and there are no dependencies 7253 05:06:45,558 --> 05:06:47,638 yet so there's no other sections to the 7254 05:06:47,638 --> 05:06:49,558 go module file so now that we're done 7255 05:06:49,558 --> 05:06:51,440 with this step the question is why does 7256 05:06:51,440 --> 05:06:54,520 go include a remote URL in module paths 7257 05:06:54,520 --> 05:06:57,958 right so this is a remote URL in theory 7258 05:06:57,958 --> 05:06:59,440 right when we push this up to GitHub 7259 05:06:59,440 --> 05:07:02,600 we'll push it up to this URL um and the 7260 05:07:02,600 --> 05:07:04,958 answ are to confuse new Gophers uh to 7261 05:07:04,958 --> 05:07:06,400 ensure that developers are using Source 7262 05:07:06,400 --> 05:07:08,120 control or to simplify remote 7263 05:07:08,120 --> 05:07:09,958 downloading of packages and it is 7264 05:07:09,958 --> 05:07:12,520 definitely that last one the next 7265 05:07:12,520 --> 05:07:15,000 question on the same step asks what is 7266 05:07:15,000 --> 05:07:18,638 Hello go in our case the repository SL 7267 05:07:18,638 --> 05:07:21,878 directory name or the module path prefix 7268 05:07:21,878 --> 05:07:24,638 and in our case it's actually the name 7269 05:07:24,638 --> 05:07:26,558 of the repository so again if we were to 7270 05:07:26,558 --> 05:07:28,718 push this up to GitHub um GitHub is the 7271 05:07:28,718 --> 05:07:30,360 name of the website where it's hosted 7272 05:07:30,360 --> 05:07:32,920 wag Lane is my namespace on GitHub and 7273 05:07:32,920 --> 05:07:35,480 hello go would be the name of the 7274 05:07:35,480 --> 05:07:37,480 directory that we are in and the name of 7275 05:07:37,480 --> 05:07:41,440 the repository up on GitHub 7276 05:07:44,798 --> 05:07:46,040 then this next question is just to make 7277 05:07:46,040 --> 05:07:48,520 sure that we completed the step properly 7278 05:07:48,520 --> 05:07:50,000 what does the first line of go dood 7279 05:07:50,000 --> 05:07:53,160 contain and it contains module followed 7280 05:07:53,160 --> 05:07:57,440 by the module path now so that VSS code 7281 05:07:57,440 --> 05:08:00,000 will work properly with all my syntax 7282 05:08:00,000 --> 05:08:01,480 highlighting with the go plugin I'm 7283 05:08:01,480 --> 05:08:06,400 actually going to reopen uh vs code to 7284 05:08:06,400 --> 05:08:08,680 that same directory the hello go 7285 05:08:08,680 --> 05:08:10,120 directory so we'll just be working 7286 05:08:10,120 --> 05:08:14,160 within this module uh for a 7287 05:08:14,160 --> 05:08:16,840 second and the instructions say inside 7288 05:08:16,840 --> 05:08:19,600 of hello go so now I'm inside of this 7289 05:08:19,600 --> 05:08:21,958 hello go directory at kind of the top 7290 05:08:21,958 --> 05:08:25,360 level of uh my vs code window um it says 7291 05:08:25,360 --> 05:08:27,080 create a new file called main.go so 7292 05:08:27,080 --> 05:08:29,280 let's go ahead and do 7293 05:08:29,280 --> 05:08:31,718 that conventionally the file in the main 7294 05:08:31,718 --> 05:08:33,440 package uh that contains the main 7295 05:08:33,440 --> 05:08:36,400 function is called main.go uh paste the 7296 05:08:36,400 --> 05:08:38,000 following code into your file Okay cool 7297 05:08:38,000 --> 05:08:40,558 so we should all be familiar with this 7298 05:08:40,558 --> 05:08:43,280 code by now right we've we've probably 7299 05:08:43,280 --> 05:08:46,160 written code like this uh I don't know 7300 05:08:46,160 --> 05:08:48,520 almost a hundred times by now in the 7301 05:08:48,520 --> 05:08:51,200 boot Dev platform next it looks like 7302 05:08:51,200 --> 05:08:53,480 we're just going to run the code using 7303 05:08:53,480 --> 05:08:57,798 the go tool chains interpreter so gun 7304 05:08:57,798 --> 05:08:59,200 main.go 7305 05:08:59,200 --> 05:09:03,000 and we get a nice hello world printed to 7306 05:09:03,000 --> 05:09:05,240 the console there's sort of two main 7307 05:09:05,240 --> 05:09:08,040 ways to run go code locally one is with 7308 05:09:08,040 --> 05:09:10,440 the G run command like we just used the 7309 05:09:10,440 --> 05:09:12,080 other is to use the go build command 7310 05:09:12,080 --> 05:09:13,878 which we'll get into in just a second 7311 05:09:13,878 --> 05:09:17,400 and actually in general I prefer the go 7312 05:09:17,400 --> 05:09:20,480 build method uh G run is really only 7313 05:09:20,480 --> 05:09:22,600 suitable for when you're running uh tiny 7314 05:09:22,600 --> 05:09:25,520 little scripts like this one and just to 7315 05:09:25,520 --> 05:09:28,320 be clear about the difference G run so 7316 05:09:28,320 --> 05:09:33,080 gun main.go runs the go code in the file 7317 05:09:33,080 --> 05:09:34,760 that we pass in right in this case 7318 05:09:34,760 --> 05:09:37,798 main.go and and that's all it does go 7319 05:09:37,798 --> 05:09:39,958 build actually builds a production 7320 05:09:39,958 --> 05:09:42,440 executable um which is how you'll use 7321 05:09:42,440 --> 05:09:44,840 your go code in the real world so I 7322 05:09:44,840 --> 05:09:46,440 typically prefer building that 7323 05:09:46,440 --> 05:09:48,280 production executable um just because 7324 05:09:48,280 --> 05:09:49,958 it's more accurately reflects how your 7325 05:09:49,958 --> 05:09:52,558 code will run in production so the 7326 05:09:52,558 --> 05:09:55,400 question on this step is does g run 7327 05:09:55,400 --> 05:09:57,718 build a production executable and the 7328 05:09:57,718 --> 05:09:59,878 answer is no it just kind of oneoff runs 7329 05:09:59,878 --> 05:10:02,240 your code it doesn't build any uh 7330 05:10:02,240 --> 05:10:04,958 production ready artifacts now at the 7331 05:10:04,958 --> 05:10:06,958 end of this same step we were asked to 7332 05:10:06,958 --> 05:10:09,000 execute the go help run command in our 7333 05:10:09,000 --> 05:10:13,320 Shelf so go help run um which just 7334 05:10:13,320 --> 05:10:15,440 prints out a bunch of help information 7335 05:10:15,440 --> 05:10:18,400 on how to use uh the G run command and 7336 05:10:18,400 --> 05:10:20,520 the question for the step says uh which 7337 05:10:20,520 --> 05:10:22,958 can go run except as arguments if we 7338 05:10:22,958 --> 05:10:24,840 scroll to the top so here's where I ran 7339 05:10:24,840 --> 05:10:27,840 go help run uh we can see the usage 7340 05:10:27,840 --> 05:10:30,320 information and it says run compiles and 7341 05:10:30,320 --> 05:10:33,160 runs the named main go package typically 7342 05:10:33,160 --> 05:10:35,558 the package is specified as a list of.go 7343 05:10:35,558 --> 05:10:37,520 source files from a single directory but 7344 05:10:37,520 --> 05:10:39,360 it can also be an import path file 7345 05:10:39,360 --> 05:10:41,920 system path or pattern matching a single 7346 05:10:41,920 --> 05:10:44,920 known package so which can go run accept 7347 05:10:44,920 --> 05:10:47,638 as arguments package names file names um 7348 05:10:47,638 --> 05:10:49,160 it actually looks like it can handle 7349 05:10:49,160 --> 05:10:51,840 both great now we get to use go build so 7350 05:10:51,840 --> 05:10:53,440 you can for the most part just forget 7351 05:10:53,440 --> 05:10:55,600 about G run you probably don't need to 7352 05:10:55,600 --> 05:10:58,680 use it um all too often so go build 7353 05:10:58,680 --> 05:11:00,520 compiles go code into an executable 7354 05:11:00,520 --> 05:11:02,440 program so all you need to do is make 7355 05:11:02,440 --> 05:11:05,160 sure that you're in the same uh kind of 7356 05:11:05,160 --> 05:11:07,320 main package that you want to build so 7357 05:11:07,320 --> 05:11:09,840 I'm here in the hell go directory 7358 05:11:09,840 --> 05:11:12,000 um I can LS to prove it to you we've got 7359 05:11:12,000 --> 05:11:14,798 the main.go file here package main Funk 7360 05:11:14,798 --> 05:11:18,520 main all that good stuff uh we'll run go 7361 05:11:18,520 --> 05:11:20,878 build we don't even need to pass in 7362 05:11:20,878 --> 05:11:23,520 package or file names it just builds uh 7363 05:11:23,520 --> 05:11:26,000 the package of the current directory so 7364 05:11:26,000 --> 05:11:28,440 as you can see here we have this new 7365 05:11:28,440 --> 05:11:32,000 executable binary in our current helloo 7366 05:11:32,000 --> 05:11:34,440 directory now if you remember way back 7367 05:11:34,440 --> 05:11:36,600 to I think chapter one of this course we 7368 05:11:36,600 --> 05:11:37,878 talked about the difference between 7369 05:11:37,878 --> 05:11:40,000 interpreted languages and and compiled 7370 05:11:40,000 --> 05:11:42,240 languages and one of the amazing things 7371 05:11:42,240 --> 05:11:45,558 about go is that we build compiled 7372 05:11:45,558 --> 05:11:48,240 executables that we can execute anywhere 7373 05:11:48,240 --> 05:11:51,240 so this hello go binary we can now copy 7374 05:11:51,240 --> 05:11:53,440 this put it on another machine and run 7375 05:11:53,440 --> 05:11:55,280 it without even needing to install the 7376 05:11:55,280 --> 05:11:57,798 go tool chain on that machine this is 7377 05:11:57,798 --> 05:12:01,280 compiled machine code so we can now run 7378 05:12:01,280 --> 05:12:03,440 this hello go program like we would any 7379 05:12:03,440 --> 05:12:07,480 other executable /hello go and it prints 7380 05:12:07,480 --> 05:12:09,480 hello world now I do want to show you a 7381 05:12:09,480 --> 05:12:11,760 little tip here because every time you 7382 05:12:11,760 --> 05:12:13,920 update your code let's say I change this 7383 05:12:13,920 --> 05:12:17,878 to hello world 2 if I just rerun hello 7384 05:12:17,878 --> 05:12:20,240 go it still will just print hello world 7385 05:12:20,240 --> 05:12:22,320 and that's because I didn't recompile my 7386 05:12:22,320 --> 05:12:24,440 code so a lot of new go developers kind 7387 05:12:24,440 --> 05:12:26,920 of forget to recompile their code and 7388 05:12:26,920 --> 05:12:28,200 they think they have bugs or their 7389 05:12:28,200 --> 05:12:29,558 codee's not doing what they expect you 7390 05:12:29,558 --> 05:12:31,320 have to recompile what I'd recommend 7391 05:12:31,320 --> 05:12:33,840 doing is just every time you update your 7392 05:12:33,840 --> 05:12:36,080 code and want to rerun it uh you should 7393 05:12:36,080 --> 05:12:37,320 build a compile and you can just do it 7394 05:12:37,320 --> 05:12:39,600 in the same step uh by doing go build 7395 05:12:39,600 --> 05:12:42,480 and then double Amper sand do/ the name 7396 05:12:42,480 --> 05:12:44,840 of your binary so this basically says 7397 05:12:44,840 --> 05:12:48,320 compile my code if that succeeds run the 7398 05:12:48,320 --> 05:12:50,520 compiled binary and the question for 7399 05:12:50,520 --> 05:12:52,400 this step is what was created after 7400 05:12:52,400 --> 05:12:54,958 running go build an executable file 7401 05:12:54,958 --> 05:12:57,080 named main an executable file named 7402 05:12:57,080 --> 05:13:00,600 hello go or a package named CMD and in 7403 05:13:00,600 --> 05:13:02,600 this case it was an executable file 7404 05:13:02,600 --> 05:13:04,958 named hello go right we've got it right 7405 05:13:04,958 --> 05:13:06,400 there it just kind of defaults to the 7406 05:13:06,400 --> 05:13:08,840 name um of the directory the next 7407 05:13:08,840 --> 05:13:10,440 question for this step is what happens 7408 05:13:10,440 --> 05:13:13,718 when you run /hello go and I actually 7409 05:13:13,718 --> 05:13:15,878 changed this to hello world to but if we 7410 05:13:15,878 --> 05:13:18,400 do it again after changing the code back 7411 05:13:18,400 --> 05:13:21,120 um the options are program panics hello 7412 05:13:21,120 --> 05:13:23,320 world is printed or the code compiles um 7413 05:13:23,320 --> 05:13:25,080 hello world is printed and it's 7414 05:13:25,080 --> 05:13:26,958 important to understand here the reason 7415 05:13:26,958 --> 05:13:29,360 we don't say the code compiles is 7416 05:13:29,360 --> 05:13:32,400 because at this Steph Helo all we are 7417 05:13:32,400 --> 05:13:34,520 doing is running the compiled binary 7418 05:13:34,520 --> 05:13:38,400 we're not recompiling the code the next 7419 05:13:38,400 --> 05:13:40,520 command in the go tool chain that we're 7420 05:13:40,520 --> 05:13:43,000 going to talk about is go install now to 7421 05:13:43,000 --> 05:13:45,040 be honest I don't use it a ton but I 7422 05:13:45,040 --> 05:13:46,320 still think it's important to understand 7423 05:13:46,320 --> 05:13:48,958 because you'll see it around okay so Ure 7424 05:13:48,958 --> 05:13:50,878 you're in your hello repo then run go 7425 05:13:50,878 --> 05:13:52,440 install so I'm here in the hello 7426 05:13:52,440 --> 05:13:55,878 directory and we run go 7427 05:13:55,878 --> 05:13:58,798 install and next we navigate out of our 7428 05:13:58,798 --> 05:14:00,080 project directory so I'm going to go up 7429 05:14:00,080 --> 05:14:01,080 one 7430 05:14:01,080 --> 05:14:04,638 level and what it's telling me is go has 7431 05:14:04,638 --> 05:14:07,400 installed the hello go program globally 7432 05:14:07,400 --> 05:14:09,480 so the go tool chain when we ran go 7433 05:14:09,480 --> 05:14:11,718 install basically compiled that code and 7434 05:14:11,718 --> 05:14:13,558 then made it globally accessible to our 7435 05:14:13,558 --> 05:14:16,520 entire machine so now if I run hello go 7436 05:14:16,520 --> 05:14:18,520 notice without the dot slash because I'm 7437 05:14:18,520 --> 05:14:20,240 not running a program in my current 7438 05:14:20,240 --> 05:14:22,120 directory I'm running now a program 7439 05:14:22,120 --> 05:14:24,040 that's in my 7440 05:14:24,040 --> 05:14:26,680 path it prints hello world so now I can 7441 05:14:26,680 --> 05:14:29,638 use this script that I built anywhere on 7442 05:14:29,638 --> 05:14:32,520 my machine which is just super useful um 7443 05:14:32,520 --> 05:14:34,638 if you're building kind of scripts for 7444 05:14:34,638 --> 05:14:36,798 your own local productivity so the 7445 05:14:36,798 --> 05:14:38,520 question for this step is what does go 7446 05:14:38,520 --> 05:14:41,000 install do saves local code to the 7447 05:14:41,000 --> 05:14:43,080 remote Source control provider installs 7448 05:14:43,080 --> 05:14:45,240 dependencies or compiles and installs 7449 05:14:45,240 --> 05:14:46,920 the program locally and the answer is 7450 05:14:46,920 --> 05:14:48,520 that it compiles and installs the 7451 05:14:48,520 --> 05:14:50,360 program locally again you would really 7452 05:14:50,360 --> 05:14:52,360 only use this if you're building scripts 7453 05:14:52,360 --> 05:14:54,638 for your own personal use on your 7454 05:14:54,638 --> 05:14:57,480 machine the next question for this same 7455 05:14:57,480 --> 05:15:00,280 step is code must be compiled with go 7456 05:15:00,280 --> 05:15:02,760 build before running go install it's 7457 05:15:02,760 --> 05:15:04,200 true false now if you were paying 7458 05:15:04,200 --> 05:15:06,120 attention you probably noticed the 7459 05:15:06,120 --> 05:15:08,638 answer here but we actually ran go 7460 05:15:08,638 --> 05:15:09,480 andall 7461 05:15:09,480 --> 05:15:12,120 without a binary existing in our current 7462 05:15:12,120 --> 05:15:14,600 directory so if I go back into the hello 7463 05:15:14,600 --> 05:15:17,200 go directory and run go install you'll 7464 05:15:17,200 --> 05:15:19,878 see there's actually no hello go binary 7465 05:15:19,878 --> 05:15:21,680 that exists here um and it works just 7466 05:15:21,680 --> 05:15:24,280 the same so the codee does not need to 7467 05:15:24,280 --> 05:15:26,520 be compiled with go build 7468 05:15:26,520 --> 05:15:29,360 first all right so we've created a main 7469 05:15:29,360 --> 05:15:32,360 package and a executable program uh now 7470 05:15:32,360 --> 05:15:34,240 we're going to build a library package a 7471 05:15:34,240 --> 05:15:37,718 custom Library package so uh what we're 7472 05:15:37,718 --> 05:15:39,760 supposed to do is create a directory at 7473 05:15:39,760 --> 05:15:41,558 the same level as the hello go directory 7474 05:15:41,558 --> 05:15:42,760 so I'm in the hell go directory 7475 05:15:42,760 --> 05:15:45,160 currently I'm going to go up one level 7476 05:15:45,160 --> 05:15:47,958 and let's see so we've got helloo in 7477 05:15:47,958 --> 05:15:49,718 here I'm going to make a new directory 7478 05:15:49,718 --> 05:15:51,280 called my 7479 05:15:51,280 --> 05:15:54,760 strings and then we'll go into my 7480 05:15:54,760 --> 05:15:57,120 strings and here we need to initialize a 7481 05:15:57,120 --> 05:16:00,320 new go module so I'll do go mod in it 7482 05:16:00,320 --> 05:16:02,920 github.com Wags 7483 05:16:02,920 --> 05:16:06,280 Lane slash my 7484 05:16:06,280 --> 05:16:09,040 strings and that module is created now 7485 05:16:09,040 --> 05:16:11,480 to get my VSS code toing all working 7486 05:16:11,480 --> 05:16:14,160 properly again I'm going to just 7487 05:16:14,160 --> 05:16:17,280 reopen VSS code to that level so we'll 7488 05:16:17,280 --> 05:16:19,120 go back and find the 7489 05:16:19,120 --> 05:16:22,000 myrings directory and open directly into 7490 05:16:22,000 --> 05:16:23,200 that 7491 05:16:23,200 --> 05:16:25,040 directory 7492 05:16:25,040 --> 05:16:27,520 okay next we create a new file called 7493 05:16:27,520 --> 05:16:30,920 myrings Dogo so this is the go dood that 7494 05:16:30,920 --> 05:16:33,040 we created with the go mod in nit 7495 05:16:33,040 --> 05:16:34,878 command and now we're creating a new 7496 05:16:34,878 --> 05:16:39,040 file called myrings Dogo 7497 05:16:39,040 --> 05:16:43,360 and we want to paste the following 7498 05:16:43,680 --> 05:16:46,760 code okay so package my strings that's 7499 05:16:46,760 --> 05:16:48,240 the first thing to notice right this is 7500 05:16:48,240 --> 05:16:50,240 not a main package so we won't be able 7501 05:16:50,240 --> 05:16:53,480 to build this package as a standalone 7502 05:16:53,480 --> 05:16:56,040 executable this package will be kind of 7503 05:16:56,040 --> 05:16:58,400 the intention is for us to use it in our 7504 05:16:58,400 --> 05:17:01,440 other hello go package the other thing 7505 05:17:01,440 --> 05:17:04,600 to notice about this code aside from the 7506 05:17:04,600 --> 05:17:07,958 package name is that there is no main 7507 05:17:07,958 --> 05:17:10,080 function here again because it's not an 7508 05:17:10,080 --> 05:17:12,240 executable program we're just going to 7509 05:17:12,240 --> 05:17:15,320 be exporting functions that can be used 7510 05:17:15,320 --> 05:17:18,080 in our main package let's talk a little 7511 05:17:18,080 --> 05:17:20,200 bit about this reverse function so this 7512 05:17:20,200 --> 05:17:22,520 is the only function in the myrings 7513 05:17:22,520 --> 05:17:25,000 package at the moment and uh you know 7514 05:17:25,000 --> 05:17:26,718 theoretically it reverses a string from 7515 05:17:26,718 --> 05:17:28,200 left to right although I haven't tested 7516 05:17:28,200 --> 05:17:30,280 it um but the important thing is that we 7517 05:17:30,280 --> 05:17:33,558 need to capitalize we need to capitalize 7518 05:17:33,558 --> 05:17:36,520 the first letter of the function's name 7519 05:17:36,520 --> 05:17:38,920 and that's because in go that's how we 7520 05:17:38,920 --> 05:17:42,520 export a function if it were little r 7521 05:17:42,520 --> 05:17:44,240 then this function would not be able to 7522 05:17:44,240 --> 05:17:46,440 be used outside of this package but we 7523 05:17:46,440 --> 05:17:48,480 want to export it because we want to be 7524 05:17:48,480 --> 05:17:50,440 able to use it in our main package right 7525 05:17:50,440 --> 05:17:52,558 in the helloo directory um and and kind 7526 05:17:52,558 --> 05:17:55,320 of import this logic and use it now 7527 05:17:55,320 --> 05:17:57,480 we're told to run the go build command 7528 05:17:57,480 --> 05:17:59,240 here in this directory and you'll notice 7529 05:17:59,240 --> 05:18:01,840 it doesn't actually seem to do anything 7530 05:18:01,840 --> 05:18:04,080 there again there was no executable file 7531 05:18:04,080 --> 05:18:05,718 that was built because this is not a 7532 05:18:05,718 --> 05:18:07,920 main package um but it is worth pointing 7533 05:18:07,920 --> 05:18:09,718 out that go build is still a useful 7534 05:18:09,718 --> 05:18:11,240 command because it checks for compile 7535 05:18:11,240 --> 05:18:13,400 time errors so for example if I uh 7536 05:18:13,400 --> 05:18:15,360 create an invalid token here and then 7537 05:18:15,360 --> 05:18:18,320 run go build uh we will get compile time 7538 05:18:18,320 --> 05:18:20,638 errors so it is um still kind of useful 7539 05:18:20,638 --> 05:18:22,760 just to make sure that this code 7540 05:18:22,760 --> 05:18:25,360 compiles so the question for the step is 7541 05:18:25,360 --> 05:18:27,680 what was the output of the go build 7542 05:18:27,680 --> 05:18:30,718 command in the library package um was it 7543 05:18:30,718 --> 05:18:32,200 an executable program or was the 7544 05:18:32,200 --> 05:18:34,000 compiled package silently saved to the 7545 05:18:34,000 --> 05:18:36,200 local build cache well we didn't get an 7546 05:18:36,200 --> 05:18:39,080 executable package right uh this is not 7547 05:18:39,080 --> 05:18:41,480 a main package so we don't get um a nice 7548 05:18:41,480 --> 05:18:43,600 runnable executable instead it is 7549 05:18:43,600 --> 05:18:45,120 silently saved to the local build cache 7550 05:18:45,120 --> 05:18:47,600 so it can be used later in an actual 7551 05:18:47,600 --> 05:18:50,600 executable program and then the next 7552 05:18:50,600 --> 05:18:53,000 question is why is the function capital 7553 05:18:53,000 --> 05:18:55,400 r reverse instead of lowercase are 7554 05:18:55,400 --> 05:18:58,360 reverse and it's lowercase names aren't 7555 05:18:58,360 --> 05:19:00,160 exported for external use or 7556 05:19:00,160 --> 05:19:01,760 conventionally uppercase names are used 7557 05:19:01,760 --> 05:19:04,200 in go the answer is that lowercase names 7558 05:19:04,200 --> 05:19:06,558 are not exported so by convention 7559 05:19:06,558 --> 05:19:09,320 functions can have either a lowercase 7560 05:19:09,320 --> 05:19:11,718 name or an uppercase name and uppercase 7561 05:19:11,718 --> 05:19:14,680 names are exported from the package so 7562 05:19:14,680 --> 05:19:16,440 this next question is does a package in 7563 05:19:16,440 --> 05:19:19,320 a folder named date parser need to also 7564 05:19:19,320 --> 05:19:21,400 be called Date parser right does the 7565 05:19:21,400 --> 05:19:23,558 package need to be date parser now 7566 05:19:23,558 --> 05:19:24,878 you'll notice that we created a 7567 05:19:24,878 --> 05:19:27,360 directory called my strings and a 7568 05:19:27,360 --> 05:19:29,920 package called my strings and if you 7569 05:19:29,920 --> 05:19:31,840 remember back to earlier in this chapter 7570 05:19:31,840 --> 05:19:34,280 we talked about how by convention that's 7571 05:19:34,280 --> 05:19:37,320 the best way to do it it's not necessary 7572 05:19:37,320 --> 05:19:40,000 um but it is it is the convention okay 7573 05:19:40,000 --> 05:19:42,840 so now let's use our reverse function 7574 05:19:42,840 --> 05:19:45,480 back in the main package in the hello 7575 05:19:45,480 --> 05:19:47,840 directory right so it says um modify 7576 05:19:47,840 --> 05:19:50,840 helloo main.go so I need to 7577 05:19:50,840 --> 05:19:54,240 reopen I'm going to open vs code back 7578 05:19:54,240 --> 05:19:59,320 into the hello go 7579 05:20:00,120 --> 05:20:02,480 directory it says modify hello Go's 7580 05:20:02,480 --> 05:20:05,798 main.go file okay so we'll use 7581 05:20:05,798 --> 05:20:08,200 parenthesis here so that we can do some 7582 05:20:08,200 --> 05:20:09,760 multip Le 7583 05:20:09,760 --> 05:20:12,760 Imports and we'll be using the import 7584 05:20:12,760 --> 05:20:16,440 path that matches the module name of our 7585 05:20:16,440 --> 05:20:18,040 my strings package so in my case it was 7586 05:20:18,040 --> 05:20:23,200 github.com Wags Lane slm 7587 05:20:23,200 --> 05:20:28,040 strings and then here we just copy this 7588 05:20:28,040 --> 05:20:30,798 code from the instructions and in fact 7589 05:20:30,798 --> 05:20:32,600 let me space this out so we can see it 7590 05:20:32,600 --> 05:20:35,280 just a little bit better Okay cool so 7591 05:20:35,280 --> 05:20:37,440 we've imported the myrings package and 7592 05:20:37,440 --> 05:20:39,480 then down in our code we we can use my 7593 05:20:39,480 --> 05:20:41,000 strings which is the name of the 7594 05:20:41,000 --> 05:20:43,160 package. 7595 05:20:43,160 --> 05:20:48,240 reverse to call that exported function 7596 05:20:48,240 --> 05:20:51,120 okay now because we've added a 7597 05:20:51,120 --> 05:20:53,480 dependency we need to update our go dood 7598 05:20:53,480 --> 05:20:57,878 file so edit the hell Go's go.mod file 7599 05:20:57,878 --> 05:20:59,160 to contain the 7600 05:20:59,160 --> 05:21:01,400 following this is the important part 7601 05:21:01,400 --> 05:21:02,200 down 7602 05:21:02,200 --> 05:21:04,718 here so we need to 7603 05:21:04,718 --> 05:21:08,000 add replace example.com username my 7604 05:21:08,000 --> 05:21:12,520 strings with do dotm strings and require 7605 05:21:12,520 --> 05:21:13,798 example.com 7606 05:21:13,798 --> 05:21:18,520 username myrings version z now I do need 7607 05:21:18,520 --> 05:21:20,400 to update this right because I didn't 7608 05:21:20,400 --> 05:21:25,798 use example.com I used github.com Wags 7609 05:21:26,080 --> 05:21:31,240 Lane now what's going on here right Go's 7610 05:21:31,240 --> 05:21:33,638 dependency management is very heavily 7611 05:21:33,638 --> 05:21:37,160 based on git and remote URLs so normally 7612 05:21:37,160 --> 05:21:39,680 what you would do is take your my 7613 05:21:39,680 --> 05:21:43,160 streams my strings package and push it 7614 05:21:43,160 --> 05:21:46,240 up to GitHub and then import it from 7615 05:21:46,240 --> 05:21:48,440 there and and sort of all of the go 7616 05:21:48,440 --> 05:21:50,680 packages in the world that require the 7617 05:21:50,680 --> 05:21:53,280 my strings package will point up to that 7618 05:21:53,280 --> 05:21:56,400 remote location that remote server what 7619 05:21:56,400 --> 05:22:00,160 we are doing here with this replace and 7620 05:22:00,160 --> 05:22:03,320 require well specifically the replace is 7621 05:22:03,320 --> 05:22:05,718 we're kind of doing a little hack to get 7622 05:22:05,718 --> 05:22:07,958 things to work locally without having to 7623 05:22:07,958 --> 05:22:10,840 publish to get so we're basically saying 7624 05:22:10,840 --> 05:22:13,798 I want you to take this string this 7625 05:22:13,798 --> 05:22:16,718 import path right github.com waglan 7626 05:22:16,718 --> 05:22:19,240 myrings and don't go look for it out on 7627 05:22:19,240 --> 05:22:22,840 the internet instead just resolve it to 7628 05:22:22,840 --> 05:22:26,120 this path dot do my strings right and 7629 05:22:26,120 --> 05:22:28,638 now because well I should probably get 7630 05:22:28,638 --> 05:22:31,200 back into the hello go 7631 05:22:31,200 --> 05:22:34,080 directory right do do/ 7632 05:22:34,080 --> 05:22:37,360 myrings this is the directory containing 7633 05:22:37,360 --> 05:22:39,160 the my strings package 7634 05:22:39,160 --> 05:22:41,080 right so we're basically just saying 7635 05:22:41,080 --> 05:22:44,200 replace this with my local uh file 7636 05:22:44,200 --> 05:22:46,920 system we're telling go how to find this 7637 05:22:46,920 --> 05:22:49,638 package on our machine so now that we've 7638 05:22:49,638 --> 05:22:52,200 made those changes uh we can build and 7639 05:22:52,200 --> 05:22:55,400 run this program again so go 7640 05:22:55,400 --> 05:22:58,240 build slh 7641 05:22:58,240 --> 05:23:01,718 heloo build and run and it looks like 7642 05:23:01,718 --> 05:23:04,760 it's working correctly this this 7643 05:23:04,760 --> 05:23:06,120 function is supposed to reverse the 7644 05:23:06,120 --> 05:23:10,440 string and we get this nasty little 7645 05:23:10,878 --> 05:23:12,718 and the question is just asking us what 7646 05:23:12,718 --> 05:23:15,520 was printed and that's what we got on 7647 05:23:15,520 --> 05:23:18,080 the same step this next question asks 7648 05:23:18,080 --> 05:23:20,200 how does the go tool chain know where to 7649 05:23:20,200 --> 05:23:23,240 find the imported code npm hosts the 7650 05:23:23,240 --> 05:23:25,200 files publicly it downloads it from 7651 05:23:25,200 --> 05:23:27,680 Google's servers we use the replace 7652 05:23:27,680 --> 05:23:30,040 keyword in the Goot dood to point it to 7653 05:23:30,040 --> 05:23:32,080 the relative location of myrings or it 7654 05:23:32,080 --> 05:23:34,080 was fetched from GitHub now again I want 7655 05:23:34,080 --> 05:23:35,638 to point out that most of the time 7656 05:23:35,638 --> 05:23:37,600 you'll be fetching code from GitHub or 7657 05:23:37,600 --> 05:23:39,798 gitlab or some remote Source when you're 7658 05:23:39,798 --> 05:23:42,600 using thirdparty dependencies in our 7659 05:23:42,600 --> 05:23:46,840 case we used this replace keyword uh to 7660 05:23:46,840 --> 05:23:49,400 point the go tool chain to the location 7661 05:23:49,400 --> 05:23:52,680 of the myrings package on our machine so 7662 05:23:52,680 --> 05:23:54,520 we already briefly talked about this but 7663 05:23:54,520 --> 05:23:57,080 I just want to reiterate that this 7664 05:23:57,080 --> 05:24:00,240 little replace hack is useful for kind 7665 05:24:00,240 --> 05:24:01,878 of testing and doing things on our local 7666 05:24:01,878 --> 05:24:04,280 machine but it's not suitable for 7667 05:24:04,280 --> 05:24:06,240 production generally what you would do 7668 05:24:06,240 --> 05:24:08,360 is push up that my strings get repos 7669 05:24:08,360 --> 05:24:10,558 repository to GitHub and then import 7670 05:24:10,558 --> 05:24:13,958 from there so you will typically not see 7671 05:24:13,958 --> 05:24:17,718 replace aliases in production go dood 7672 05:24:17,718 --> 05:24:21,000 files very often you'll just see um 7673 05:24:21,000 --> 05:24:24,360 packages sort of required vanilla from 7674 05:24:24,360 --> 05:24:26,558 their remote location so now we're going 7675 05:24:26,558 --> 05:24:29,360 to practice using a remote thirdparty 7676 05:24:29,360 --> 05:24:31,480 module says create a new directory in 7677 05:24:31,480 --> 05:24:33,680 the same uh Parent Directory as hello 7678 05:24:33,680 --> 05:24:36,638 and myrings called Date test so let's go 7679 05:24:36,638 --> 05:24:39,360 back up one level and create a new 7680 05:24:39,360 --> 05:24:43,600 directory make dur date test and then 7681 05:24:43,600 --> 05:24:45,798 I'm going to go ahead and again reopen 7682 05:24:45,798 --> 05:24:47,718 vs 7683 05:24:47,718 --> 05:24:52,600 code into that 7684 05:24:53,200 --> 05:24:56,600 directory okay create a main.go with 7685 05:24:56,600 --> 05:24:57,440 this 7686 05:24:57,440 --> 05:25:00,958 code we can do 7687 05:25:04,280 --> 05:25:09,240 that next initialize a module so we do 7688 05:25:09,240 --> 05:25:13,120 to go mod and it and again I'll just use 7689 05:25:13,120 --> 05:25:13,840 good 7690 05:25:13,840 --> 05:25:18,558 hub.com Wags Lane SL date 7691 05:25:18,558 --> 05:25:21,798 test creating new go.mod to add module 7692 05:25:21,798 --> 05:25:24,200 requirements and Subs do go mod tidy 7693 05:25:24,200 --> 05:25:26,920 okay cool um I'm going to ignore that 7694 05:25:26,920 --> 05:25:28,320 for just a second and instead I'm going 7695 05:25:28,320 --> 05:25:29,480 to follow the instructions it says 7696 05:25:29,480 --> 05:25:31,240 download and install the remote go tiny 7697 05:25:31,240 --> 05:25:33,480 date package using go 7698 05:25:33,480 --> 05:25:36,040 get Okay so we've used go install in the 7699 05:25:36,040 --> 05:25:38,360 past right go install installs an 7700 05:25:38,360 --> 05:25:40,400 executable on our machine to be used 7701 05:25:40,400 --> 05:25:43,520 anywhere um goget is how we go download 7702 05:25:43,520 --> 05:25:46,040 and install third party dependencies so 7703 05:25:46,040 --> 05:25:48,760 we're going and grabbing the github.com 7704 05:25:48,760 --> 05:25:53,440 waglan slgo tiny time 7705 05:25:53,440 --> 05:25:56,440 module and it gets added 7706 05:25:56,440 --> 05:26:00,280 automatically to our go.mod you'll see 7707 05:26:00,280 --> 05:26:03,320 that it just kind of grabs the latest 7708 05:26:03,320 --> 05:26:06,080 version cool um print the contents of 7709 05:26:06,080 --> 05:26:08,400 your go onod uh I don't need to run that 7710 05:26:08,400 --> 05:26:09,798 because we've got it open here in vs 7711 05:26:09,798 --> 05:26:11,680 code um and then compile and run our 7712 05:26:11,680 --> 05:26:16,240 program again so let's do that go 7713 05:26:16,240 --> 05:26:20,958 build and run and it's going to compile 7714 05:26:20,958 --> 05:26:23,680 to a file called Date test right because 7715 05:26:23,680 --> 05:26:26,360 that's the name of our 7716 05:26:27,920 --> 05:26:30,600 directory cool and as you can see it's 7717 05:26:30,600 --> 05:26:33,520 printing out this date here so what did 7718 05:26:33,520 --> 05:26:37,840 we do right we used goget to download 7719 05:26:37,840 --> 05:26:40,120 code from this remote location which 7720 05:26:40,120 --> 05:26:42,320 also happens to be the import path right 7721 05:26:42,320 --> 05:26:44,958 because that's how go packages work 7722 05:26:44,958 --> 05:26:47,360 typically so let me go grab that and 7723 05:26:47,360 --> 05:26:51,000 just show you this 7724 05:26:51,000 --> 05:26:53,920 is this is a package that's hosted on 7725 05:26:53,920 --> 05:26:55,520 GitHub so the go tool chain actually 7726 05:26:55,520 --> 05:26:58,280 went to GitHub and downloaded this code 7727 05:26:58,280 --> 05:27:01,400 right added it to the go dood as a 7728 05:27:01,400 --> 05:27:03,400 dependency and then created this new 7729 05:27:03,400 --> 05:27:06,718 file called go. sum that kind of 7730 05:27:06,718 --> 05:27:10,160 contains any uh transient dependencies 7731 05:27:10,160 --> 05:27:13,760 or dependencies used by the go tiny time 7732 05:27:13,760 --> 05:27:15,320 package that we just imported so kind of 7733 05:27:15,320 --> 05:27:17,160 keeps track of everything that we're 7734 05:27:17,160 --> 05:27:19,200 using and the question for this one is 7735 05:27:19,200 --> 05:27:21,040 how did the go tool chain know where to 7736 05:27:21,040 --> 05:27:24,958 download the Go tiny time package oh man 7737 05:27:24,958 --> 05:27:27,080 this uh this question is not optimized 7738 05:27:27,080 --> 05:27:30,200 for this ridiculously zoomed in view it 7739 05:27:30,200 --> 05:27:31,878 says the module import path is used for 7740 05:27:31,878 --> 05:27:35,240 remote lookups EG github.com Wags Lane 7741 05:27:35,240 --> 05:27:37,718 go timing time um or the go tool chain 7742 05:27:37,718 --> 05:27:40,080 has free open source go modules location 7743 05:27:40,080 --> 05:27:42,638 memorized uh that is not true it just it 7744 05:27:42,638 --> 05:27:44,638 just does a remote lookup right it goes 7745 05:27:44,638 --> 05:27:48,958 and fetches that from the remote git URL 7746 05:27:48,958 --> 05:27:50,200 and then just to make sure that we did 7747 05:27:50,200 --> 05:27:52,840 the step correctly uh it's asking us 7748 05:27:52,840 --> 05:27:54,160 what was printed after running the new 7749 05:27:54,160 --> 05:27:57,040 date test program can see it right there 7750 05:27:57,040 --> 05:27:58,958 it looks like it's this 7751 05:27:58,958 --> 05:28:02,520 2020-4 d03 right it's it's this 7752 05:28:02,520 --> 05:28:09,120 hardcoded date in RFC 3339 format 7753 05:28:09,120 --> 05:28:10,638 so hopefully that last section gave you 7754 05:28:10,638 --> 05:28:12,638 a taste of local development at least 7755 05:28:12,638 --> 05:28:14,040 showing you how to build and compile 7756 05:28:14,040 --> 05:28:15,920 some code on your own machine we'll 7757 05:28:15,920 --> 05:28:17,718 obviously be doing a lot more local 7758 05:28:17,718 --> 05:28:19,160 development at the end of this video 7759 05:28:19,160 --> 05:28:21,160 with the project uh but for now for the 7760 05:28:21,160 --> 05:28:22,520 rest of this course we'll be back 7761 05:28:22,520 --> 05:28:25,320 working in the boot Dev web interface 7762 05:28:25,320 --> 05:28:28,360 cool so we're on to talking about clean 7763 05:28:28,360 --> 05:28:31,240 packages and this is kind of just a an 7764 05:28:31,240 --> 05:28:33,120 article that I'm not going to bother 7765 05:28:33,120 --> 05:28:35,320 reading out loud on screen but I'll talk 7766 05:28:35,320 --> 05:28:37,878 about each individual section as the 7767 05:28:37,878 --> 05:28:40,240 question questions are asked so the 7768 05:28:40,240 --> 05:28:43,718 question is should you export code from 7769 05:28:43,718 --> 05:28:46,638 the main package and that's talked about 7770 05:28:46,638 --> 05:28:49,240 um down here it's basically simple don't 7771 05:28:49,240 --> 05:28:50,878 export code from the main package and if 7772 05:28:50,878 --> 05:28:52,080 you think about it it makes sense 7773 05:28:52,080 --> 05:28:54,120 there's no reason to capitalize function 7774 05:28:54,120 --> 05:28:56,520 names in the main package because no 7775 05:28:56,520 --> 05:28:59,120 other packages can import from a main 7776 05:28:59,120 --> 05:29:01,440 package a main package is built into its 7777 05:29:01,440 --> 05:29:03,558 own Standalone executable it's not a 7778 05:29:03,558 --> 05:29:07,000 library so capitalizing functions in the 7779 05:29:07,000 --> 05:29:08,680 main package is just kind kind of 7780 05:29:08,680 --> 05:29:10,958 confusing because it kind of signals to 7781 05:29:10,958 --> 05:29:12,638 developers that you're writing code 7782 05:29:12,638 --> 05:29:16,160 that's meant to be imported and it's 7783 05:29:16,160 --> 05:29:19,000 not this next question says when should 7784 05:29:19,000 --> 05:29:22,558 you not export a function variable or 7785 05:29:22,558 --> 05:29:26,040 type now this is an interesting question 7786 05:29:26,040 --> 05:29:28,240 I think a lot of newer developers think 7787 05:29:28,240 --> 05:29:30,638 well maybe I should just export more 7788 05:29:30,638 --> 05:29:33,558 stuff because maybe the users of my 7789 05:29:33,558 --> 05:29:35,920 package will find it useful um you 7790 05:29:35,920 --> 05:29:38,040 actually want to think in the reverse 7791 05:29:38,040 --> 05:29:40,680 you want to export as few things as 7792 05:29:40,680 --> 05:29:42,798 possible when you're building Library 7793 05:29:42,798 --> 05:29:45,080 packages because anytime you export a 7794 05:29:45,080 --> 05:29:48,400 function you now need to support that 7795 05:29:48,400 --> 05:29:50,160 function right you can't really take it 7796 05:29:50,160 --> 05:29:52,920 away later everyone's code will break 7797 05:29:52,920 --> 05:29:54,320 right so you should really think about 7798 05:29:54,320 --> 05:29:57,120 what you're exposing to your users as 7799 05:29:57,120 --> 05:29:59,480 like the surface area of a shape and you 7800 05:29:59,480 --> 05:30:01,760 want to keep that surface area as small 7801 05:30:01,760 --> 05:30:03,760 as possible to keep the maintenance 7802 05:30:03,760 --> 05:30:06,160 burden down and to make your package 7803 05:30:06,160 --> 05:30:08,958 easy to use right the few things that 7804 05:30:08,958 --> 05:30:10,798 your users need to know about in order 7805 05:30:10,798 --> 05:30:12,798 to effectively use your package the 7806 05:30:12,798 --> 05:30:15,360 easier it'll be to use so when should 7807 05:30:15,360 --> 05:30:17,200 you not export a function variable or 7808 05:30:17,200 --> 05:30:19,760 type um when the end user doesn't need 7809 05:30:19,760 --> 05:30:22,160 to know about it hide everything that 7810 05:30:22,160 --> 05:30:25,200 they don't need to know about the next 7811 05:30:25,200 --> 05:30:27,320 question is should you often change a 7812 05:30:27,320 --> 05:30:30,558 packages exported API so API stands for 7813 05:30:30,558 --> 05:30:32,638 application programming interface and 7814 05:30:32,638 --> 05:30:34,760 basically anytime you export something 7815 05:30:34,760 --> 05:30:37,600 from a library package uh you're adding 7816 05:30:37,600 --> 05:30:41,080 that thing to the package's API right 7817 05:30:41,080 --> 05:30:43,520 it's the interface that other developers 7818 05:30:43,520 --> 05:30:46,520 will use to access your package so 7819 05:30:46,520 --> 05:30:48,280 should you often change a package's 7820 05:30:48,280 --> 05:30:51,040 exported API the answer is that no you 7821 05:30:51,040 --> 05:30:52,920 should try to keep changes to your 7822 05:30:52,920 --> 05:30:55,440 internal functionality right imagine if 7823 05:30:55,440 --> 05:30:57,520 the go programming language uh let's say 7824 05:30:57,520 --> 05:31:00,320 the standard Library changed fmt do 7825 05:31:00,320 --> 05:31:04,280 print line to fm. print right and just 7826 05:31:04,280 --> 05:31:07,760 removed fm. print line that would break 7827 05:31:07,760 --> 05:31:09,920 and an immense amount of code right so 7828 05:31:09,920 --> 05:31:11,920 you don't want to go about uh publishing 7829 05:31:11,920 --> 05:31:13,958 packages that you intend to kind of 7830 05:31:13,958 --> 05:31:17,200 update the API for uh very rapidly 7831 05:31:17,200 --> 05:31:20,878 stable apis are good apis so should you 7832 05:31:20,878 --> 05:31:23,000 often change a package as exported API 7833 05:31:23,000 --> 05:31:25,400 no try to keep the changes to internal 7834 05:31:25,400 --> 05:31:27,440 functionality yes move fast and break 7835 05:31:27,440 --> 05:31:30,638 things or if the package is main then 7836 05:31:30,638 --> 05:31:34,120 yes uh the answer is just no try to keep 7837 05:31:34,120 --> 05:31:37,280 changes to internal functionality again 7838 05:31:37,280 --> 05:31:39,400 if the package is main then it's 7839 05:31:39,400 --> 05:31:41,798 irrelevant because you're not building 7840 05:31:41,798 --> 05:31:42,878 uh a 7841 05:31:42,878 --> 05:31:44,798 library I want to talk about the 7842 05:31:44,798 --> 05:31:47,000 difference between concurrent or 7843 05:31:47,000 --> 05:31:50,000 parallel programming and synchronous or 7844 05:31:50,000 --> 05:31:52,200 sequential programming now it's worth 7845 05:31:52,200 --> 05:31:53,638 pointing out at this point that 7846 05:31:53,638 --> 05:31:56,000 concurrency and parallelism are 7847 05:31:56,000 --> 05:31:57,798 different and we'll talk about their 7848 05:31:57,798 --> 05:31:59,958 differences in a future course for for 7849 05:31:59,958 --> 05:32:02,000 now we're going to kind of treat them as 7850 05:32:02,000 --> 05:32:03,400 the same idea and I'll just kind of 7851 05:32:03,400 --> 05:32:06,080 refer to them as concurrency uh 7852 05:32:06,080 --> 05:32:08,440 similarly sequential Pro programming and 7853 05:32:08,440 --> 05:32:10,280 synchronous they're slightly different 7854 05:32:10,280 --> 05:32:12,120 terms but um I'm going to kind of bucket 7855 05:32:12,120 --> 05:32:14,240 them for the purpose of this discussion 7856 05:32:14,240 --> 05:32:16,878 we'll be really comparing uh concurrent 7857 05:32:16,878 --> 05:32:19,520 code to synchronous uh or sequential 7858 05:32:19,520 --> 05:32:21,240 code so let's start with the easy one 7859 05:32:21,240 --> 05:32:22,558 let's talk about synchronous or 7860 05:32:22,558 --> 05:32:25,520 sequential programming say we have some 7861 05:32:25,520 --> 05:32:30,040 code x colal 5 7862 05:32:30,040 --> 05:32:35,600 x++ and then maybe fmt do print. 7863 05:32:35,600 --> 05:32:38,680 print line 7864 05:32:38,680 --> 05:32:41,360 X the nice thing about this code and 7865 05:32:41,360 --> 05:32:43,600 what makes it synchronous or sequential 7866 05:32:43,600 --> 05:32:45,600 is that the code executes in order from 7867 05:32:45,600 --> 05:32:47,320 top to bottom right first we create a 7868 05:32:47,320 --> 05:32:49,718 variable named X set equal to 5 then we 7869 05:32:49,718 --> 05:32:52,440 increment it by one and then we print X 7870 05:32:52,440 --> 05:32:54,680 right everything's happening in order 7871 05:32:54,680 --> 05:32:57,638 from top to bottom one thing at a time 7872 05:32:57,638 --> 05:33:00,280 now this is usually what you want it's 7873 05:33:00,280 --> 05:33:02,120 simple it's easy to reason about it's 7874 05:33:02,120 --> 05:33:04,600 easy to write code this way the problem 7875 05:33:04,600 --> 05:33:07,000 is sometimes it's not the most efficient 7876 05:33:07,000 --> 05:33:09,840 way to write performance code or code 7877 05:33:09,840 --> 05:33:13,000 that can run as fast as possible on a 7878 05:33:13,000 --> 05:33:15,320 given set of Hardware so in order to 7879 05:33:15,320 --> 05:33:17,040 understand how we can maybe optimize 7880 05:33:17,040 --> 05:33:19,440 this we need to look into how your 7881 05:33:19,440 --> 05:33:20,920 computer's 7882 05:33:20,920 --> 05:33:25,240 CPU or Central Processing Unit 7883 05:33:25,240 --> 05:33:29,080 works so your CPU has a clock speed um 7884 05:33:29,080 --> 05:33:31,440 which basically like from a very high 7885 05:33:31,440 --> 05:33:33,958 level means how many instructions how 7886 05:33:33,958 --> 05:33:34,878 many 7887 05:33:34,878 --> 05:33:38,558 instructions it can do per let's say set 7888 05:33:38,558 --> 05:33:40,120 those aren't necessarily the units but 7889 05:33:40,120 --> 05:33:42,360 it is basically how many computations it 7890 05:33:42,360 --> 05:33:45,840 can do um per amount of time we just say 7891 05:33:45,840 --> 05:33:49,200 it seconds to keep things simple okay so 7892 05:33:49,200 --> 05:33:50,558 when we're analyzing this code over here 7893 05:33:50,558 --> 05:33:52,080 on the right basically what needs to 7894 05:33:52,080 --> 05:33:54,638 happen is first we set x equal to five 7895 05:33:54,638 --> 05:33:57,680 and that takes up one instruction right 7896 05:33:57,680 --> 05:33:59,480 after that we get to increment X by six 7897 05:33:59,480 --> 05:34:01,200 that'll take up another instruction and 7898 05:34:01,200 --> 05:34:04,558 then we get to print X so the speed at 7899 05:34:04,558 --> 05:34:07,000 which we can execute this little program 7900 05:34:07,000 --> 05:34:11,240 here is dependent on how fast the cpu's 7901 05:34:11,240 --> 05:34:13,718 clock speed is so if we want our program 7902 05:34:13,718 --> 05:34:15,440 to go faster we can basically do one of 7903 05:34:15,440 --> 05:34:17,798 two things either we can reduce the 7904 05:34:17,798 --> 05:34:20,760 number of instructions required uh for 7905 05:34:20,760 --> 05:34:24,280 our program to execute or we can get a 7906 05:34:24,280 --> 05:34:26,600 faster CPU one that can do more 7907 05:34:26,600 --> 05:34:29,160 instructions per second the problem is 7908 05:34:29,160 --> 05:34:32,360 getting a faster CPU sometimes is really 7909 05:34:32,360 --> 05:34:35,280 really expensive and so instead of 7910 05:34:35,280 --> 05:34:37,840 getting a faster CPU what we've kind 7911 05:34:37,840 --> 05:34:40,718 have done over the years is instead add 7912 05:34:40,718 --> 05:34:42,320 more 7913 05:34:42,320 --> 05:34:45,240 CPUs and in this case um we've kind of 7914 05:34:45,240 --> 05:34:47,798 broken the CPU up actually into what we 7915 05:34:47,798 --> 05:34:49,878 call different cores so you might 7916 05:34:49,878 --> 05:34:52,840 actually have a quad core processor Each 7917 05:34:52,840 --> 05:34:56,600 of which let's say does I don't know 7918 05:34:56,600 --> 05:35:00,638 5,000 instructions per Nan I'm totally 7919 05:35:00,638 --> 05:35:03,160 making these units up um but you get the 7920 05:35:03,160 --> 05:35:06,240 idea any one of these CPU cores can only 7921 05:35:06,240 --> 05:35:09,120 do 5,000 but the interest thing is they 7922 05:35:09,120 --> 05:35:13,120 can all do 5,000 per nond at the same 7923 05:35:13,120 --> 05:35:16,718 time so if we distribute our program 7924 05:35:16,718 --> 05:35:19,080 across all of the cores in theory we 7925 05:35:19,080 --> 05:35:20,638 should able to go uh we should be able 7926 05:35:20,638 --> 05:35:25,040 to go about four times as fast again if 7927 05:35:25,040 --> 05:35:27,280 we use all four cores instead of just 7928 05:35:27,280 --> 05:35:30,120 one the problem is that most code we 7929 05:35:30,120 --> 05:35:33,120 write can't take advantage of all four 7930 05:35:33,120 --> 05:35:34,878 cores for example let's look at this 7931 05:35:34,878 --> 05:35:37,280 code over here we set x equal to 5 and 7932 05:35:37,280 --> 05:35:38,878 then we increment it and then we print 7933 05:35:38,878 --> 05:35:42,600 it it has to happen in 1 2 7934 05:35:42,600 --> 05:35:46,760 3 right in order 1 2 3 we can't do all 7935 05:35:46,760 --> 05:35:48,558 of these instructions at the same time 7936 05:35:48,558 --> 05:35:52,000 if we did then x++ would have nothing to 7937 05:35:52,000 --> 05:35:53,360 increment because we never would have 7938 05:35:53,360 --> 05:35:55,958 set um an X variable equal to five in 7939 05:35:55,958 --> 05:35:58,718 the first place and print line X would 7940 05:35:58,718 --> 05:36:00,760 have nothing to print because X hasn't 7941 05:36:00,760 --> 05:36:04,280 been set yet so writing concurrent or 7942 05:36:04,280 --> 05:36:07,200 parallel code can drastically speed up 7943 05:36:07,200 --> 05:36:08,798 the performance of our programs because 7944 05:36:08,798 --> 05:36:11,200 we're able to distribute um kind of all 7945 05:36:11,200 --> 05:36:13,080 the instructions that we need to compute 7946 05:36:13,080 --> 05:36:15,558 across multiple cores the problem is we 7947 05:36:15,558 --> 05:36:17,558 do actually need to write our code in a 7948 05:36:17,558 --> 05:36:20,558 different way we need to expect that 7949 05:36:20,558 --> 05:36:22,360 some of the instructions are going to 7950 05:36:22,360 --> 05:36:24,638 happen at the same time and that's 7951 05:36:24,638 --> 05:36:26,520 what's going to speed up our program so 7952 05:36:26,520 --> 05:36:28,920 let's say we had a little bit more code 7953 05:36:28,920 --> 05:36:31,718 in our program here maybe we have X or 7954 05:36:31,718 --> 05:36:33,958 excuse me y colal 7955 05:36:33,958 --> 05:36:36,040 6 y 7956 05:36:36,040 --> 05:36:38,240 -- FM 7957 05:36:38,240 --> 05:36:39,840 t. 7958 05:36:39,840 --> 05:36:41,400 print 7959 05:36:41,400 --> 05:36:43,200 line 7960 05:36:43,200 --> 05:36:48,000 Y okay this code here in this block kind 7961 05:36:48,000 --> 05:36:49,718 of dependent on each other right we have 7962 05:36:49,718 --> 05:36:53,320 to do it in one two three order um and 7963 05:36:53,320 --> 05:36:55,958 the same goes for this block here but we 7964 05:36:55,958 --> 05:36:58,878 don't have to necessarily do this block 7965 05:36:58,878 --> 05:37:01,680 of code where we calculate and print X 7966 05:37:01,680 --> 05:37:03,760 before or after we calculate and print y 7967 05:37:03,760 --> 05:37:05,080 they're they're kind of separate in that 7968 05:37:05,080 --> 05:37:06,718 way so what we can actually do is take 7969 05:37:06,718 --> 05:37:08,840 this block of code code and execute it 7970 05:37:08,840 --> 05:37:11,440 in one core and at the same time execute 7971 05:37:11,440 --> 05:37:14,360 this other block of code in another core 7972 05:37:14,360 --> 05:37:16,360 doing them at the same time so let's 7973 05:37:16,360 --> 05:37:18,878 sort of visualize the runtime of this 7974 05:37:18,878 --> 05:37:21,558 program here if we run this code 7975 05:37:21,558 --> 05:37:23,840 synchronously or sequentially right not 7976 05:37:23,840 --> 05:37:25,920 taking advantage of two CPU cores but 7977 05:37:25,920 --> 05:37:27,760 instead of doing it all in one core then 7978 05:37:27,760 --> 05:37:29,400 our running time might look something 7979 05:37:29,400 --> 05:37:34,160 like this I don't know let's just say 6 7980 05:37:34,160 --> 05:37:37,638 nond but instead if we run it across two 7981 05:37:37,638 --> 05:37:40,160 cores in 7982 05:37:40,160 --> 05:37:45,200 parallel each core executes at the same 7983 05:37:45,200 --> 05:37:47,680 time and they'll each take approximately 7984 05:37:47,680 --> 05:37:50,400 let's say three 7985 05:37:50,400 --> 05:37:53,240 nond so we're done in half the time 7986 05:37:53,240 --> 05:37:55,040 again because we took advantage of the 7987 05:37:55,040 --> 05:37:57,760 hardware that was available to us so to 7988 05:37:57,760 --> 05:38:01,280 wrap up writing concurrent code in many 7989 05:38:01,280 --> 05:38:05,360 cases can drastically reduce of how long 7990 05:38:05,360 --> 05:38:07,558 it takes to run our programs and it 7991 05:38:07,558 --> 05:38:09,200 depends just a little bit on kind of 7992 05:38:09,200 --> 05:38:11,320 fundamentally what we're trying to do so 7993 05:38:11,320 --> 05:38:13,120 in this case we literally could take a 7994 05:38:13,120 --> 05:38:16,600 program and chop its runtime in half by 7995 05:38:16,600 --> 05:38:19,400 utilizing a little bit more Hardware so 7996 05:38:19,400 --> 05:38:20,958 this chapter is going to be all about 7997 05:38:20,958 --> 05:38:23,160 concurrency in the go programm language 7998 05:38:23,160 --> 05:38:26,280 and the great thing about go is how easy 7999 05:38:26,280 --> 05:38:29,160 it makes it to write concurrent code so 8000 05:38:29,160 --> 05:38:30,878 the question is how do we write 8001 05:38:30,878 --> 05:38:33,718 concurrent code and go what's the syntax 8002 05:38:33,718 --> 05:38:36,240 well there's actually a really awesome 8003 05:38:36,240 --> 05:38:38,360 builtin keyword word to the go program 8004 05:38:38,360 --> 05:38:42,400 language the go keyword and it spawns a 8005 05:38:42,400 --> 05:38:45,360 new go routine when you use it now a go 8006 05:38:45,360 --> 05:38:48,160 routine is kind of unique to the go 8007 05:38:48,160 --> 05:38:50,120 programming language but at a high level 8008 05:38:50,120 --> 05:38:51,920 you can just think of it as a separate 8009 05:38:51,920 --> 05:38:54,240 thread of execution we're essentially 8010 05:38:54,240 --> 05:38:56,760 telling the go programming language hey 8011 05:38:56,760 --> 05:38:59,000 all this stuff in this function right 8012 05:38:59,000 --> 05:39:01,440 that I'm calling with the go keyword can 8013 05:39:01,440 --> 05:39:03,760 happen in parallel right we can go 8014 05:39:03,760 --> 05:39:06,878 execute that on another core of the CPU 8015 05:39:06,878 --> 05:39:09,680 if we need to so whenever we use the go 8016 05:39:09,680 --> 05:39:12,840 keyword execution kind of immediately 8017 05:39:12,840 --> 05:39:15,520 jumps to the next step after the 8018 05:39:15,520 --> 05:39:18,558 function call right so this do something 8019 05:39:18,558 --> 05:39:21,878 function will kind of go be executed in 8020 05:39:21,878 --> 05:39:24,240 parallel right and then execution 8021 05:39:24,240 --> 05:39:26,638 continues in the current function um 8022 05:39:26,638 --> 05:39:28,520 kind of just on the next line and then 8023 05:39:28,520 --> 05:39:30,360 as a last note before we jump into some 8024 05:39:30,360 --> 05:39:32,600 code to see how this really works when 8025 05:39:32,600 --> 05:39:35,280 we use the go keyword we're not able to 8026 05:39:35,280 --> 05:39:38,000 capture any return values from this 8027 05:39:38,000 --> 05:39:39,840 function call which makes sense right 8028 05:39:39,840 --> 05:39:42,200 because we're kind of moving on we can't 8029 05:39:42,200 --> 05:39:44,638 wait for the function to finish and 8030 05:39:44,638 --> 05:39:46,280 return some stuff that's the whole point 8031 05:39:46,280 --> 05:39:48,320 we want the function to go kind of do 8032 05:39:48,320 --> 05:39:51,200 its thing on another thread so let's try 8033 05:39:51,200 --> 05:39:53,478 this out in an assignment says emo we 8034 05:39:53,478 --> 05:39:55,920 send a lot of network requests right 8035 05:39:55,920 --> 05:39:58,638 requests over the Internet each email we 8036 05:39:58,638 --> 05:39:59,958 send must go out over the internet to 8037 05:39:59,958 --> 05:40:01,638 serve our millions of customers we need 8038 05:40:01,638 --> 05:40:03,320 to we need a single go program to be 8039 05:40:03,320 --> 05:40:05,120 capable of sending thousands of emails 8040 05:40:05,120 --> 05:40:06,718 at once right so we need to be able to 8041 05:40:06,718 --> 05:40:08,080 do lots of things things at once this is 8042 05:40:08,080 --> 05:40:11,478 what go routines allow us to do edit the 8043 05:40:11,478 --> 05:40:13,400 send email function to execute its 8044 05:40:13,400 --> 05:40:15,400 Anonymous function concurrently so that 8045 05:40:15,400 --> 05:40:18,120 the received message prints after the 8046 05:40:18,120 --> 05:40:20,080 sent message so let's go ahead and run 8047 05:40:20,080 --> 05:40:23,360 the code in its current 8048 05:40:25,798 --> 05:40:29,280 state and we get email received hello 8049 05:40:29,280 --> 05:40:31,638 there Stacy email sent hello there Stacy 8050 05:40:31,638 --> 05:40:34,160 right so it looks out of order now 8051 05:40:34,160 --> 05:40:36,440 here's our send email function it takes 8052 05:40:36,440 --> 05:40:41,520 a message um as a string parameter and 8053 05:40:41,520 --> 05:40:43,160 the interesting thing is it calls this 8054 05:40:43,160 --> 05:40:44,920 Anonymous function here right so it's 8055 05:40:44,920 --> 05:40:46,320 defining this function and then 8056 05:40:46,320 --> 05:40:48,798 immediately calling it um where it's 8057 05:40:48,798 --> 05:40:51,520 going to wait for 250 milliseconds and 8058 05:40:51,520 --> 05:40:54,878 then print email received and then this 8059 05:40:54,878 --> 05:40:57,400 function will exit and it will print 8060 05:40:57,400 --> 05:40:58,920 email sent right and then print the 8061 05:40:58,920 --> 05:41:00,558 message so again that's why this is out 8062 05:41:00,558 --> 05:41:02,320 of order right we're we're executing 8063 05:41:02,320 --> 05:41:04,400 this function first and then we're 8064 05:41:04,400 --> 05:41:07,558 moving on to the next line so the way we 8065 05:41:07,558 --> 05:41:10,400 fix this is by using the go 8066 05:41:10,400 --> 05:41:13,840 keyword to execute this bit of code at 8067 05:41:13,840 --> 05:41:17,160 the same time is this bit of code right 8068 05:41:17,160 --> 05:41:18,638 the go keyword will immediately move 8069 05:41:18,638 --> 05:41:21,320 down to line 13 on the main thread or 8070 05:41:21,320 --> 05:41:24,000 the main go routine and spawn a new go 8071 05:41:24,000 --> 05:41:25,840 routine to kind of do this in the 8072 05:41:25,840 --> 05:41:29,120 background and because of this waiting 8073 05:41:29,120 --> 05:41:32,400 time the email received message should 8074 05:41:32,400 --> 05:41:35,440 happen afterwards so let's go ahead and 8075 05:41:35,440 --> 05:41:39,040 run this again 8076 05:41:40,400 --> 05:41:42,280 sent received sent received looks good 8077 05:41:42,280 --> 05:41:45,478 to me so you may have been thinking to 8078 05:41:45,478 --> 05:41:47,760 yourself well how useful is it to call a 8079 05:41:47,760 --> 05:41:49,760 function in a go routine if I can't even 8080 05:41:49,760 --> 05:41:52,958 get the return values the answer in go 8081 05:41:52,958 --> 05:41:55,840 is that we use channels typically to 8082 05:41:55,840 --> 05:41:58,520 kind of resynchronize our code so 8083 05:41:58,520 --> 05:42:01,558 typically we'll use go routines or the 8084 05:42:01,558 --> 05:42:04,160 go keyword plus some function to go do a 8085 05:42:04,160 --> 05:42:05,958 bunch of computation all at the same 8086 05:42:05,958 --> 05:42:07,680 time and then we can kind of 8087 05:42:07,680 --> 05:42:09,760 resynchronize either in the main go 8088 05:42:09,760 --> 05:42:12,120 routine or in some other go routine by 8089 05:42:12,120 --> 05:42:14,440 passing data back and forth between go 8090 05:42:14,440 --> 05:42:17,958 routines using channels a channel is 8091 05:42:17,958 --> 05:42:20,760 really just a thread safe or go routine 8092 05:42:20,760 --> 05:42:25,000 safe cue we can put stuff in one end and 8093 05:42:25,000 --> 05:42:26,958 read it out the other end in the same 8094 05:42:26,958 --> 05:42:29,600 order so we'll typically have one or 8095 05:42:29,600 --> 05:42:32,200 more go routines kind of sending data 8096 05:42:32,200 --> 05:42:33,958 into the channel maybe they finished a 8097 05:42:33,958 --> 05:42:35,840 calculation they're returning their 8098 05:42:35,840 --> 05:42:37,520 results over the channel and then we'll 8099 05:42:37,520 --> 05:42:39,920 have one or more go routines on the 8100 05:42:39,920 --> 05:42:42,240 other end reading that data off of the 8101 05:42:42,240 --> 05:42:44,120 channel and processing it in some way 8102 05:42:44,120 --> 05:42:46,280 maybe sending a report maybe printing it 8103 05:42:46,280 --> 05:42:49,200 to the console so this is the Syntax for 8104 05:42:49,200 --> 05:42:51,478 making a channel and channels are typed 8105 05:42:51,478 --> 05:42:53,920 so we can say this is a channel of 8106 05:42:53,920 --> 05:42:56,520 integers and then we can send data into 8107 05:42:56,520 --> 05:42:58,958 the channel using this Arrow operator 8108 05:42:58,958 --> 05:43:00,558 it's it's really pretty intuitive we're 8109 05:43:00,558 --> 05:43:04,080 saying 69 is being sent into the channel 8110 05:43:04,080 --> 05:43:06,320 and then it's actually the same operator 8111 05:43:06,320 --> 05:43:08,478 to read a a value out of a channel we 8112 05:43:08,478 --> 05:43:10,320 just move it over to the other side 8113 05:43:10,320 --> 05:43:12,080 again super intuitive we're reading a 8114 05:43:12,080 --> 05:43:14,878 value out of the channel and saving it 8115 05:43:14,878 --> 05:43:17,680 into the variable V in this example now 8116 05:43:17,680 --> 05:43:19,478 it's important to understand that both 8117 05:43:19,478 --> 05:43:21,878 of these operations sending and 8118 05:43:21,878 --> 05:43:23,760 receiving on a channel are blocking 8119 05:43:23,760 --> 05:43:27,280 operations so if I'm trying to send a 8120 05:43:27,280 --> 05:43:30,040 value into a channel and there's no 8121 05:43:30,040 --> 05:43:31,840 other go routine on the other side that 8122 05:43:31,840 --> 05:43:33,920 will be able to read it out then my code 8123 05:43:33,920 --> 05:43:37,200 will actually stop and wait on this go 8124 05:43:37,200 --> 05:43:39,798 routine until there is a reader ready 8125 05:43:39,798 --> 05:43:42,160 and the same goes for reading when a go 8126 05:43:42,160 --> 05:43:44,760 routine gets to this section of code if 8127 05:43:44,760 --> 05:43:47,280 there's nothing being sent into the 8128 05:43:47,280 --> 05:43:49,878 channel on another go routine then this 8129 05:43:49,878 --> 05:43:52,080 code will just sit and wait until 8130 05:43:52,080 --> 05:43:54,360 something is sent so let's move on to 8131 05:43:54,360 --> 05:43:56,558 the assignment says run the program 8132 05:43:56,558 --> 05:43:58,680 you'll see that it Deadlocks and never 8133 05:43:58,680 --> 05:44:00,840 exits so a deadlock is basically when 8134 05:44:00,840 --> 05:44:03,040 all the go routines in a program are 8135 05:44:03,040 --> 05:44:05,040 blocking and there's nothing for them to 8136 05:44:05,040 --> 05:44:07,120 do it means there's a bug in the code so 8137 05:44:07,120 --> 05:44:09,000 let's run the code just to see what that 8138 05:44:09,000 --> 05:44:11,958 feels like although I think it's just 8139 05:44:11,958 --> 05:44:13,360 going to feel like it's running the code 8140 05:44:13,360 --> 05:44:15,000 for a long time so I'm going to go and 8141 05:44:15,000 --> 05:44:16,718 cancel 8142 05:44:16,718 --> 05:44:19,400 that the filter old emails function is 8143 05:44:19,400 --> 05:44:20,958 trying to send on a channel and there's 8144 05:44:20,958 --> 05:44:22,400 no other go routin running that can 8145 05:44:22,400 --> 05:44:23,840 accept the value from the channel okay 8146 05:44:23,840 --> 05:44:25,878 so let's take a look filter old emails 8147 05:44:25,878 --> 05:44:29,440 takes some emails as an input creates an 8148 05:44:29,440 --> 05:44:31,280 is old Channel and that looks like it 8149 05:44:31,280 --> 05:44:33,558 Loops over the emails and if they are 8150 05:44:33,558 --> 05:44:35,798 before a certain date it's going to pass 8151 05:44:35,798 --> 05:44:37,638 the Boolean true into the channel 8152 05:44:37,638 --> 05:44:39,280 otherwise it's going to pass in false 8153 05:44:39,280 --> 05:44:42,558 and then once that Loop exits it's going 8154 05:44:42,558 --> 05:44:46,478 to read out of the channel here and 8155 05:44:46,478 --> 05:44:48,600 print to the console you know whether or 8156 05:44:48,600 --> 05:44:52,760 not the emails uh were old Okay 8157 05:44:52,760 --> 05:44:55,000 cool so this makes sense this makes 8158 05:44:55,000 --> 05:44:56,920 sense why this is blocking right this 8159 05:44:56,920 --> 05:44:59,160 first send either here or here which 8160 05:44:59,160 --> 05:45:01,878 everyone happens first is going to block 8161 05:45:01,878 --> 05:45:03,160 because the 8162 05:45:03,160 --> 05:45:05,920 reader like that code hasn't happened 8163 05:45:05,920 --> 05:45:08,120 yet this is the same this is the same go 8164 05:45:08,120 --> 05:45:10,840 routine right this is not happening at 8165 05:45:10,840 --> 05:45:12,680 the same time as this is happening so 8166 05:45:12,680 --> 05:45:14,680 we'll use a go routine to fix it fix the 8167 05:45:14,680 --> 05:45:16,000 deadlock by spawning an anonymous go 8168 05:45:16,000 --> 05:45:18,718 routine to write to the is old Channel 8169 05:45:18,718 --> 05:45:20,000 instead of using the same go routine 8170 05:45:20,000 --> 05:45:21,638 that's reading from it okay cool so we 8171 05:45:21,638 --> 05:45:24,120 need to run this Loop essentially in a 8172 05:45:24,120 --> 05:45:29,000 new go routine so we'll do go Funk and 8173 05:45:29,000 --> 05:45:30,320 we'll just use an anonymous function 8174 05:45:30,320 --> 05:45:31,920 here because we don't really care about 8175 05:45:31,920 --> 05:45:33,558 naming 8176 05:45:33,558 --> 05:45:36,080 it and we'll just run that entire block 8177 05:45:36,080 --> 05:45:37,520 of code 8178 05:45:37,520 --> 05:45:40,040 in a new Anonymous function so now this 8179 05:45:40,040 --> 05:45:42,638 and this will happen at the same time 8180 05:45:42,638 --> 05:45:45,360 let's go ahead and run 8181 05:45:47,360 --> 05:45:50,040 that cool and this looks like what I 8182 05:45:50,040 --> 05:45:51,478 would expect I'll go ahead and submit 8183 05:45:51,478 --> 05:45:55,160 that so there's this concept of a token 8184 05:45:55,160 --> 05:45:57,120 when we're talking about concurrent 8185 05:45:57,120 --> 05:46:00,638 programs a a token is basically a unary 8186 05:46:00,638 --> 05:46:02,440 value right so not not binary there's 8187 05:46:02,440 --> 05:46:04,478 not two possible values true and false 8188 05:46:04,478 --> 05:46:06,718 unary there's just one possible value 8189 05:46:06,718 --> 05:46:08,680 and when there's just one possible value 8190 05:46:08,680 --> 05:46:11,240 we really don't care much about that 8191 05:46:11,240 --> 05:46:13,600 value it's not interesting in any way 8192 05:46:13,600 --> 05:46:15,798 right so it's not that we care what is 8193 05:46:15,798 --> 05:46:17,600 passed when we're working with tokens 8194 05:46:17,600 --> 05:46:20,520 it's that we care when and if something 8195 05:46:20,520 --> 05:46:23,440 is passed through a Channel at all so 8196 05:46:23,440 --> 05:46:26,280 for example this code here is reading a 8197 05:46:26,280 --> 05:46:29,400 value out of this Channel and it's just 8198 05:46:29,400 --> 05:46:31,360 discarding whatever it reads out it 8199 05:46:31,360 --> 05:46:33,478 doesn't even care what it is it's just 8200 05:46:33,478 --> 05:46:36,958 waiting to see uh kind of when something 8201 05:46:36,958 --> 05:46:38,958 thing comes through the channel so let's 8202 05:46:38,958 --> 05:46:41,080 move on to the assignment um and kind of 8203 05:46:41,080 --> 05:46:43,160 put that into practice it says our maleo 8204 05:46:43,160 --> 05:46:44,958 server isn't able to boot up until it 8205 05:46:44,958 --> 05:46:46,240 receives the signal that all of its 8206 05:46:46,240 --> 05:46:48,478 databases are online and it learns about 8207 05:46:48,478 --> 05:46:50,600 them being online by waiting for tokens 8208 05:46:50,600 --> 05:46:52,760 which are just empty structs um on a 8209 05:46:52,760 --> 05:46:55,080 channel complete the wait for DBS 8210 05:46:55,080 --> 05:46:56,798 function it should block until it 8211 05:46:56,798 --> 05:47:00,680 receives numb DBS so this integer here 8212 05:47:00,680 --> 05:47:04,638 um tokens on the DB Chan channel right 8213 05:47:04,638 --> 05:47:06,478 so this is a channel of empty structs 8214 05:47:06,478 --> 05:47:08,360 and again empty structs are tokens 8215 05:47:08,360 --> 05:47:10,240 they're unary values um they're not 8216 05:47:10,240 --> 05:47:12,600 interesting they don't have any Fields 8217 05:47:12,600 --> 05:47:14,280 each time it reads a token the get 8218 05:47:14,280 --> 05:47:16,200 databases Channel go routine will print 8219 05:47:16,200 --> 05:47:18,478 a message to the console for you okay so 8220 05:47:18,478 --> 05:47:20,360 I'm guessing that's down here yeah it 8221 05:47:20,360 --> 05:47:22,878 looks like it's going to watch um and 8222 05:47:22,878 --> 05:47:26,478 and print here okay so let's get started 8223 05:47:26,478 --> 05:47:27,958 and write some 8224 05:47:27,958 --> 05:47:30,040 code it should block until it receives 8225 05:47:30,040 --> 05:47:32,798 numb DB's tokens so it's a variable 8226 05:47:32,798 --> 05:47:35,120 amount of tokens so I guess the easiest 8227 05:47:35,120 --> 05:47:36,558 way to do this would be for with a loop 8228 05:47:36,558 --> 05:47:39,718 so 4 I col equals 8229 05:47:39,718 --> 05:47:44,520 0 I is less than num 8230 05:47:44,520 --> 05:47:46,798 DBS I 8231 05:47:46,798 --> 05:47:49,120 ++ and then in here we're just going to 8232 05:47:49,120 --> 05:47:52,320 wait for a token to come across the DB 8233 05:47:52,320 --> 05:47:54,478 channel right so it'll block once and 8234 05:47:54,478 --> 05:47:55,798 then it'll move on to the next iteration 8235 05:47:55,798 --> 05:47:58,478 of the loop block again move on until 8236 05:47:58,478 --> 05:48:01,878 we've waited for you know numb DB's 8237 05:48:01,878 --> 05:48:04,440 tokens um and then block until it 8238 05:48:04,440 --> 05:48:05,680 receives the tokens each time it reads a 8239 05:48:05,680 --> 05:48:08,200 token that's it looks like we don't have 8240 05:48:08,200 --> 05:48:12,478 to return anything so let's run 8241 05:48:13,240 --> 05:48:15,878 that database one is online two is 8242 05:48:15,878 --> 05:48:18,558 online this looks good to me so now 8243 05:48:18,558 --> 05:48:21,040 let's talk about buffered channels so 8244 05:48:21,040 --> 05:48:22,400 the channels we've been using up until 8245 05:48:22,400 --> 05:48:23,958 this point haven't really stored 8246 05:48:23,958 --> 05:48:26,040 anything in them right we needed a 8247 05:48:26,040 --> 05:48:28,440 sender and a receiver at the same time 8248 05:48:28,440 --> 05:48:30,680 as soon as the sender sends the receiver 8249 05:48:30,680 --> 05:48:32,400 receives there's nothing kind of stored 8250 05:48:32,400 --> 05:48:35,280 in the channel at any given time but 8251 05:48:35,280 --> 05:48:38,120 that is exactly what a buffered channel 8252 05:48:38,120 --> 05:48:40,120 is so we have a buffer of some length 8253 05:48:40,120 --> 05:48:42,760 let's say five different items and 8254 05:48:42,760 --> 05:48:44,878 senders can actually send into the 8255 05:48:44,878 --> 05:48:48,200 channel even when there's no receivers 8256 05:48:48,200 --> 05:48:51,000 until the buffer fills up so a sender 8257 05:48:51,000 --> 05:48:52,840 could send five things into the channel 8258 05:48:52,840 --> 05:48:54,638 and then the buffer is full the channel 8259 05:48:54,638 --> 05:48:57,638 is full right and when a receiver 8260 05:48:57,638 --> 05:48:59,920 finally goes to read and pop items off 8261 05:48:59,920 --> 05:49:01,958 of the other end it will read and pop 8262 05:49:01,958 --> 05:49:04,760 them off in order one by one until the 8263 05:49:04,760 --> 05:49:07,240 channel is empty so this this is the 8264 05:49:07,240 --> 05:49:09,360 syntax we'd use if we want to make a 8265 05:49:09,360 --> 05:49:11,680 Channel of integers with a buffer size 8266 05:49:11,680 --> 05:49:14,440 of 100 we just use that optional second 8267 05:49:14,440 --> 05:49:16,478 parameter um to the built-in make 8268 05:49:16,478 --> 05:49:18,080 function so let's move on to the 8269 05:49:18,080 --> 05:49:19,760 assignment it says we want to be able to 8270 05:49:19,760 --> 05:49:22,920 send emails in batches a writing go 8271 05:49:22,920 --> 05:49:24,520 routine we'll take an entire batch of 8272 05:49:24,520 --> 05:49:26,478 email messages to a buffer channel uh 8273 05:49:26,478 --> 05:49:28,320 we'll write an entire batch of email 8274 05:49:28,320 --> 05:49:30,040 messages to a buffer Channel and later 8275 05:49:30,040 --> 05:49:32,240 once the channel is full a reading go 8276 05:49:32,240 --> 05:49:33,920 routine will go read all of those 8277 05:49:33,920 --> 05:49:35,798 messages so we can actually go find 8278 05:49:35,798 --> 05:49:39,600 where that's happening here in the test 8279 05:49:39,798 --> 05:49:43,638 Suite okay here so send emails um oh 8280 05:49:43,638 --> 05:49:44,920 nope this is where they're getting read 8281 05:49:44,920 --> 05:49:48,360 I'm sorry ah I'm silly the function that 8282 05:49:48,360 --> 05:49:50,878 we'll be working on is what's writing 8283 05:49:50,878 --> 05:49:53,840 into the channel so emails to send is 8284 05:49:53,840 --> 05:49:55,600 the channel um we're supposed to write 8285 05:49:55,600 --> 05:49:57,440 an entire batch of emails into the 8286 05:49:57,440 --> 05:49:59,520 channel and then theoretically sometime 8287 05:49:59,520 --> 05:50:01,040 in the 8288 05:50:01,040 --> 05:50:04,638 future those emails will be read out of 8289 05:50:04,638 --> 05:50:07,600 the channel and actually sent off 8290 05:50:07,600 --> 05:50:10,240 Okay cool so what happens if I run the 8291 05:50:10,240 --> 05:50:12,478 code in its current 8292 05:50:12,478 --> 05:50:14,958 state I'm kind of imagining that it's 8293 05:50:14,958 --> 05:50:17,360 going to block 8294 05:50:17,360 --> 05:50:20,680 forever yeah that's never going to exit 8295 05:50:20,680 --> 05:50:24,400 so at emails toq is getting called here 8296 05:50:24,400 --> 05:50:27,240 and send emails is getting called here 8297 05:50:27,240 --> 05:50:29,240 and notice that they're getting called 8298 05:50:29,240 --> 05:50:31,280 on the same they're both running in the 8299 05:50:31,280 --> 05:50:34,718 same go routine Right add emails to Q is 8300 05:50:34,718 --> 05:50:36,360 there's no go keyword anywhere that I 8301 05:50:36,360 --> 05:50:39,360 see so that's why we are blocking here 8302 05:50:39,360 --> 05:50:42,638 there's no reader on the other end right 8303 05:50:42,638 --> 05:50:45,120 but because we want to do this batching 8304 05:50:45,120 --> 05:50:47,400 we actually should be able to do it all 8305 05:50:47,400 --> 05:50:49,920 on the same thread we just need a big 8306 05:50:49,920 --> 05:50:52,798 enough batch size so we need a 8307 05:50:52,798 --> 05:50:55,798 buffer if we buffer this emails to send 8308 05:50:55,798 --> 05:51:00,760 Channel with the length of the emails 8309 05:51:00,760 --> 05:51:03,320 slice then we should have enough room to 8310 05:51:03,320 --> 05:51:04,920 push all of the emails into the buffer 8311 05:51:04,920 --> 05:51:08,558 Channel let's go ahead and try that 8312 05:51:09,240 --> 05:51:12,600 cool that looks like it is working 8313 05:51:12,600 --> 05:51:15,360 channels in go can actually be closed 8314 05:51:15,360 --> 05:51:17,760 and there's really only one reason you'd 8315 05:51:17,760 --> 05:51:19,760 want to close a go Channel and it's to 8316 05:51:19,760 --> 05:51:22,080 indicate that you're done with it a 8317 05:51:22,080 --> 05:51:24,120 channel should always be closed from the 8318 05:51:24,120 --> 05:51:26,600 sending side so the sending go routine 8319 05:51:26,600 --> 05:51:28,040 the one that's pushing values into the 8320 05:51:28,040 --> 05:51:29,638 channel will be the one to close the 8321 05:51:29,638 --> 05:51:31,360 channel and that will indicate to any 8322 05:51:31,360 --> 05:51:33,040 readers of the channel That this channel 8323 05:51:33,040 --> 05:51:35,160 is closed there's nothing else to read 8324 05:51:35,160 --> 05:51:38,240 from it and the actual syntax is really 8325 05:51:38,240 --> 05:51:40,400 simple it's just the built-in close 8326 05:51:40,400 --> 05:51:42,440 function where we pass in the channel 8327 05:51:42,440 --> 05:51:44,558 itself now on the reading side we can 8328 05:51:44,558 --> 05:51:48,400 actually check if a channel is closed 8329 05:51:48,400 --> 05:51:50,840 using this kind of optional second 8330 05:51:50,840 --> 05:51:52,920 variable um that comes back when reading 8331 05:51:52,920 --> 05:51:54,680 a channel this okay variable it's a 8332 05:51:54,680 --> 05:51:57,040 Boolean uh if the Boolean is true the 8333 05:51:57,040 --> 05:51:58,958 channel is open if it is false the 8334 05:51:58,958 --> 05:52:01,840 channel is closed if the channel happens 8335 05:52:01,840 --> 05:52:05,000 to be buffered then okay will remain 8336 05:52:05,000 --> 05:52:07,920 true until the channel is emptied out so 8337 05:52:07,920 --> 05:52:10,440 okay will only be false once the buffer 8338 05:52:10,440 --> 05:52:13,878 channel is empty and closed the last 8339 05:52:13,878 --> 05:52:15,240 thing I'll mention before we jump into 8340 05:52:15,240 --> 05:52:17,200 the assignment is that you never want to 8341 05:52:17,200 --> 05:52:20,200 send a value across a closed Channel if 8342 05:52:20,200 --> 05:52:23,160 you do that go routine will panic and 8343 05:52:23,160 --> 05:52:24,558 that's why it's really important that 8344 05:52:24,558 --> 05:52:26,798 you only ever close a channel from the 8345 05:52:26,798 --> 05:52:29,558 sending side because that go routine is 8346 05:52:29,558 --> 05:52:31,360 going to be the one that knows when it's 8347 05:52:31,360 --> 05:52:34,040 done sending values okay on to the 8348 05:52:34,040 --> 05:52:36,520 assignment it says Amo we're all about 8349 05:52:36,520 --> 05:52:38,600 tring what our systems are up to with 8350 05:52:38,600 --> 05:52:40,958 great logging and Telemetry the send 8351 05:52:40,958 --> 05:52:42,440 reports function sends out a batch of 8352 05:52:42,440 --> 05:52:44,240 reports to our clients and reports back 8353 05:52:44,240 --> 05:52:46,240 how many were sent across a channel it 8354 05:52:46,240 --> 05:52:48,638 closes the channel when it's done okay 8355 05:52:48,638 --> 05:52:52,958 so the send reports function here sends 8356 05:52:52,958 --> 05:52:54,680 the reports or sends the number of 8357 05:52:54,680 --> 05:52:56,040 reports across the channel and closes 8358 05:52:56,040 --> 05:52:57,240 the channel 8359 05:52:57,240 --> 05:53:00,240 great complete the count reports 8360 05:53:00,240 --> 05:53:02,478 function it should use an infinite for 8361 05:53:02,478 --> 05:53:04,558 Loop to read from the channel if the 8362 05:53:04,558 --> 05:53:06,920 channel is closed break out of the loop 8363 05:53:06,920 --> 05:53:08,440 otherwise keep a running total of the 8364 05:53:08,440 --> 05:53:10,320 number of reports sent and return the 8365 05:53:10,320 --> 05:53:13,958 total number of responses Okay cool so 8366 05:53:13,958 --> 05:53:16,840 first things first we need to keep track 8367 05:53:16,840 --> 05:53:21,280 of a total so let's start it at 8368 05:53:21,280 --> 05:53:23,440 zero and we know that at the end of the 8369 05:53:23,440 --> 05:53:24,680 function we'll be 8370 05:53:24,680 --> 05:53:26,520 returning the 8371 05:53:26,520 --> 05:53:28,040 total 8372 05:53:28,040 --> 05:53:30,400 right then it says use an infinite for 8373 05:53:30,400 --> 05:53:33,280 Loop to read from the channel okay so 8374 05:53:33,280 --> 05:53:36,440 four um and then we need to read from 8375 05:53:36,440 --> 05:53:41,400 from the channel so we'll do um nums 8376 05:53:41,400 --> 05:53:45,760 Cent and read from the nums Cent 8377 05:53:46,878 --> 05:53:48,958 Channel okay if the channels closed 8378 05:53:48,958 --> 05:53:50,280 break out of the loop ah right so we 8379 05:53:50,280 --> 05:53:52,400 need to use that syntax to check if the 8380 05:53:52,400 --> 05:53:55,120 channel is closed so if not okay if the 8381 05:53:55,120 --> 05:53:57,760 channel is closed then we'll 8382 05:53:57,760 --> 05:54:00,160 return 8383 05:54:00,160 --> 05:54:02,320 total or I suppose we're returning down 8384 05:54:02,320 --> 05:54:03,840 here so we could just break let's just 8385 05:54:03,840 --> 05:54:07,160 do that instead break 8386 05:54:07,160 --> 05:54:10,320 otherwise uh we do total plus equals 8387 05:54:10,320 --> 05:54:12,440 nums Cent and it's important to 8388 05:54:12,440 --> 05:54:14,958 understand that as soon as okay is false 8389 05:54:14,958 --> 05:54:16,638 num scent will just be a zero value so 8390 05:54:16,638 --> 05:54:18,160 it's not a valid value that was sent 8391 05:54:18,160 --> 05:54:20,638 across the channel so it's safe to just 8392 05:54:20,638 --> 05:54:23,240 just break like that okay cool this is 8393 05:54:23,240 --> 05:54:25,600 looking correct to me let's go ahead and 8394 05:54:25,600 --> 05:54:28,360 run 8395 05:54:30,878 --> 05:54:34,920 that let's see batch of 15 38 and 61 8396 05:54:34,920 --> 05:54:38,080 Cent do those add up to 114 uh looks 8397 05:54:38,080 --> 05:54:42,200 like they might uh like my terrible in 8398 05:54:42,200 --> 05:54:44,638 in my head arithmetic says that that's 8399 05:54:44,638 --> 05:54:45,798 perfect so I'm going to go ahead and 8400 05:54:45,798 --> 05:54:48,440 submit it the range keyword works with 8401 05:54:48,440 --> 05:54:51,680 channels as well as slices and Maps so 8402 05:54:51,680 --> 05:54:53,558 we can actually range over the channel 8403 05:54:53,558 --> 05:54:56,680 and it will block until a value is ready 8404 05:54:56,680 --> 05:54:59,240 it will read it into in this case the 8405 05:54:59,240 --> 05:55:01,958 variable item and then execute the body 8406 05:55:01,958 --> 05:55:03,400 and it will do that over and over and 8407 05:55:03,400 --> 05:55:05,520 over for each new value coming across 8408 05:55:05,520 --> 05:55:08,520 the channel um and we'll only exit the 8409 05:55:08,520 --> 05:55:11,120 loop once the channel is closed so onto 8410 05:55:11,120 --> 05:55:12,718 the assignment it says it's that time 8411 05:55:12,718 --> 05:55:14,520 again maleo is hiring and we've been 8412 05:55:14,520 --> 05:55:17,160 assigned to do the interviews for some 8413 05:55:17,160 --> 05:55:19,440 reason the Fibonacci sequence is melo's 8414 05:55:19,440 --> 05:55:21,440 interview problem of choice we've been 8415 05:55:21,440 --> 05:55:23,040 tasked with building a small toy program 8416 05:55:23,040 --> 05:55:25,478 that we can use in the interview okay so 8417 05:55:25,478 --> 05:55:28,000 complete the concurrent Fibonacci 8418 05:55:28,000 --> 05:55:29,638 function if you're not familiar with the 8419 05:55:29,638 --> 05:55:31,680 Fibonacci sequence um I don't want to go 8420 05:55:31,680 --> 05:55:33,958 like too crazy far into it but it's 8421 05:55:33,958 --> 05:55:37,040 basically this sequence of numbers here 8422 05:55:37,040 --> 05:55:41,200 where each number is the sum of the two 8423 05:55:41,200 --> 05:55:44,320 preceding numbers so 1 and 2 equal 3 2 8424 05:55:44,320 --> 05:55:46,280 and three equal 5 in fact you probably 8425 05:55:46,280 --> 05:55:48,200 can't even see that let me Zoom this in 8426 05:55:48,200 --> 05:55:51,240 a little bit so 1 and one or 1 and two 8427 05:55:51,240 --> 05:55:55,840 equal 3 2 and 3 equal 5 3 and 5 equal 8 8428 05:55:55,840 --> 05:55:57,280 right so it's just this kind of set 8429 05:55:57,280 --> 05:55:59,478 sequence of 8430 05:55:59,478 --> 05:56:01,958 numbers okay complete the concurrent FIB 8431 05:56:01,958 --> 05:56:03,320 function it should create a new channel 8432 05:56:03,320 --> 05:56:05,878 of ins so let's go ahead and do that so 8433 05:56:05,878 --> 05:56:06,798 Channel 8434 05:56:06,798 --> 05:56:12,280 ins make channel of ins great call 8435 05:56:12,280 --> 05:56:15,160 Fibonacci in a go routine passing to it 8436 05:56:15,160 --> 05:56:17,878 the channel and the number of Fibonacci 8437 05:56:17,878 --> 05:56:19,638 numbers to generate okay so we have a 8438 05:56:19,638 --> 05:56:22,400 Fibonacci function here and it takes the 8439 05:56:22,400 --> 05:56:25,638 numbers and the channel itself so let's 8440 05:56:25,638 --> 05:56:28,760 start a go routine in an anonymous 8441 05:56:28,760 --> 05:56:30,558 function go 8442 05:56:30,558 --> 05:56:32,638 Funk call the 8443 05:56:32,638 --> 05:56:36,600 function um and in here we we call 8444 05:56:36,600 --> 05:56:38,718 Fibonacci let me just copy and paste 8445 05:56:38,718 --> 05:56:41,160 that because I can't spell 8446 05:56:41,160 --> 05:56:45,120 it uh it takes n 8447 05:56:45,120 --> 05:56:50,840 and this channel of in as input 8448 05:56:50,840 --> 05:56:54,040 okay then use a Range Loop to read from 8449 05:56:54,040 --> 05:56:55,280 the channel and print out the numbers 8450 05:56:55,280 --> 05:56:56,878 one by one each on a new line okay so 8451 05:56:56,878 --> 05:56:59,558 the Fibonacci function is going to pass 8452 05:56:59,558 --> 05:57:03,320 its results back over this channel so 8453 05:57:03,320 --> 05:57:06,440 it's it's taking the channel and it's 8454 05:57:06,440 --> 05:57:08,840 going to act as the sender on the 8455 05:57:08,840 --> 05:57:12,558 channel so we down here below um kind of 8456 05:57:12,558 --> 05:57:14,160 where we're spawning that go routine 8457 05:57:14,160 --> 05:57:18,638 need to act as the reader so for V and 8458 05:57:18,638 --> 05:57:21,878 range Channel 8459 05:57:23,440 --> 05:57:26,600 events print out the numbers one by 8460 05:57:26,600 --> 05:57:29,080 one print line 8461 05:57:29,080 --> 05:57:32,478 V and then when the Fibonacci function 8462 05:57:32,478 --> 05:57:34,400 is done it will close the channel so 8463 05:57:34,400 --> 05:57:37,160 we'll exit from the loop cool let's go 8464 05:57:37,160 --> 05:57:39,760 ahead and run 8465 05:57:41,040 --> 05:57:44,320 that does this look accurate 10 numbers 8466 05:57:44,320 --> 05:57:49,080 0er and one 0 + 1 is 1 1 + 2 is 3 2 + 3 8467 05:57:49,080 --> 05:57:52,400 is 5 looking good to me on to select 8468 05:57:52,400 --> 05:57:54,760 statements so a select statement is 8469 05:57:54,760 --> 05:57:56,520 similar to a switch statement if you're 8470 05:57:56,520 --> 05:57:58,440 familiar with switch statements from 8471 05:57:58,440 --> 05:58:00,320 other languages or from go where it's 8472 05:58:00,320 --> 05:58:03,718 kind of this if else uh chain and we're 8473 05:58:03,718 --> 05:58:05,478 really looking to kind of match a 8474 05:58:05,478 --> 05:58:07,200 specific case but what's interesting 8475 05:58:07,200 --> 05:58:08,638 about select statements is they're 8476 05:58:08,638 --> 05:58:11,120 unique to channels and they basically 8477 05:58:11,120 --> 05:58:14,718 let us listen on two different channels 8478 05:58:14,718 --> 05:58:18,080 and kind of execute one block of code um 8479 05:58:18,080 --> 05:58:20,840 or or or rather execute a block of code 8480 05:58:20,840 --> 05:58:24,160 for the channel that sends a value the 8481 05:58:24,160 --> 05:58:26,240 soonest so we can kind of simultaneously 8482 05:58:26,240 --> 05:58:28,600 listen on both channels and if this 8483 05:58:28,600 --> 05:58:30,558 channel sends a value first then we'll 8484 05:58:30,558 --> 05:58:32,920 do you know one thing otherwise when 8485 05:58:32,920 --> 05:58:34,440 this one sends something we'll do 8486 05:58:34,440 --> 05:58:37,000 another thing so one go r can kind of 8487 05:58:37,000 --> 05:58:39,600 process events from multiple channels at 8488 05:58:39,600 --> 05:58:41,638 the same time using a select statement 8489 05:58:41,638 --> 05:58:44,200 so this is the syntax here we create a 8490 05:58:44,200 --> 05:58:47,558 select block and then multiple cases one 8491 05:58:47,558 --> 05:58:49,840 for each channel that we are interested 8492 05:58:49,840 --> 05:58:52,280 in kind of listening for values on or 8493 05:58:52,280 --> 05:58:55,718 reading uh values off of so if this 8494 05:58:55,718 --> 05:58:58,840 channel ins has a value ready then this 8495 05:58:58,840 --> 05:59:01,638 case will be executed otherwise if this 8496 05:59:01,638 --> 05:59:04,000 one uh if Channel strings has a value 8497 05:59:04,000 --> 05:59:07,520 ready then this case will be executed if 8498 05:59:07,520 --> 05:59:09,638 both have a value ready at the same time 8499 05:59:09,638 --> 05:59:12,000 then one will be chosen randomly so you 8500 05:59:12,000 --> 05:59:13,600 don't want to kind of be dependent on 8501 05:59:13,600 --> 05:59:16,040 any weird ordering um basically as stuff 8502 05:59:16,040 --> 05:59:18,360 comes across it's going to get processed 8503 05:59:18,360 --> 05:59:20,280 so on to the assignment it says complete 8504 05:59:20,280 --> 05:59:21,840 the log messages function using an 8505 05:59:21,840 --> 05:59:23,240 infinite for Loop and a select statement 8506 05:59:23,240 --> 05:59:25,120 to log the emails and SMS messages as 8507 05:59:25,120 --> 05:59:26,520 they come across the two channels okay 8508 05:59:26,520 --> 05:59:28,360 so channel of emails channel of SMS 8509 05:59:28,360 --> 05:59:30,840 messages add a condition to return from 8510 05:59:30,840 --> 05:59:31,920 the function when one of the two 8511 05:59:31,920 --> 05:59:34,120 channels closes whichever is first um 8512 05:59:34,120 --> 05:59:36,040 use the log SMS and log email function 8513 05:59:36,040 --> 05:59:38,520 functions to log the messages Okay cool 8514 05:59:38,520 --> 05:59:42,920 so uh infinite for Loop start there and 8515 05:59:42,920 --> 05:59:46,120 inside we'll need to 8516 05:59:46,680 --> 05:59:49,520 select can use this as our syntax guide 8517 05:59:49,520 --> 05:59:53,160 over here U we got case uh 8518 05:59:53,160 --> 05:59:55,920 email 8519 05:59:55,920 --> 06:00:00,360 okay value from channel of 8520 06:00:00,920 --> 06:00:03,760 emails if that case fires then we say if 8521 06:00:03,760 --> 06:00:06,240 not okay so if the channel is closed we 8522 06:00:06,240 --> 06:00:08,160 just return and this function returns 8523 06:00:08,160 --> 06:00:11,120 nothing so we just naked return um 8524 06:00:11,120 --> 06:00:14,840 otherwise we need to log email I think 8525 06:00:14,840 --> 06:00:18,798 that's yeah log email there it is the 8526 06:00:18,798 --> 06:00:24,080 email cool other case uh sms okay from 8527 06:00:24,080 --> 06:00:26,638 the channel of 8528 06:00:26,638 --> 06:00:29,240 SMS if not 8529 06:00:29,240 --> 06:00:31,558 okay 8530 06:00:31,558 --> 06:00:33,920 return 8531 06:00:33,920 --> 06:00:37,920 otherwise log the 8532 06:00:38,440 --> 06:00:40,760 right so this for Loop will just go 8533 06:00:40,760 --> 06:00:43,360 forever until one of these two channels 8534 06:00:43,360 --> 06:00:46,160 closes in which case it'll return right 8535 06:00:46,160 --> 06:00:48,240 and it's important that we return before 8536 06:00:48,240 --> 06:00:50,520 we do the logging because when a channel 8537 06:00:50,520 --> 06:00:54,638 closes the okay variable um is false and 8538 06:00:54,638 --> 06:00:58,920 a zero value comes across the channel um 8539 06:00:58,920 --> 06:01:00,558 that wasn't sent into the channel if 8540 06:01:00,558 --> 06:01:01,840 that makes sense so like the closure 8541 06:01:01,840 --> 06:01:05,120 happens after the last value comes out 8542 06:01:05,120 --> 06:01:07,920 let's go ahead and run that 8543 06:01:10,840 --> 06:01:14,120 looking good to me we'll submit it the 8544 06:01:14,120 --> 06:01:17,718 select statement also has a default case 8545 06:01:17,718 --> 06:01:19,798 you don't always need to use the default 8546 06:01:19,798 --> 06:01:22,120 case and basically the default case only 8547 06:01:22,120 --> 06:01:25,120 fires if you're interested in 8548 06:01:25,120 --> 06:01:27,798 nonblocking so for example this select 8549 06:01:27,798 --> 06:01:32,638 block here will fire the case uh that 8550 06:01:32,638 --> 06:01:34,840 kind of pulls this V value out of this 8551 06:01:34,840 --> 06:01:37,478 channel if there is a value ready to be 8552 06:01:37,478 --> 06:01:39,558 pulled at the time that we enter the 8553 06:01:39,558 --> 06:01:41,920 select block if there's not a value 8554 06:01:41,920 --> 06:01:44,240 ready to be read out of the channel um 8555 06:01:44,240 --> 06:01:46,240 then the default case is fired 8556 06:01:46,240 --> 06:01:48,200 immediately so it kind of turns the 8557 06:01:48,200 --> 06:01:51,080 select block into a nonblocking block of 8558 06:01:51,080 --> 06:01:52,760 code and then there's a few things we're 8559 06:01:52,760 --> 06:01:54,440 going to need to know for this 8560 06:01:54,440 --> 06:01:56,718 assignment the first are these uh 8561 06:01:56,718 --> 06:01:59,440 several standard Library functions so 8562 06:01:59,440 --> 06:02:02,320 time. tick returns a channel that sends 8563 06:02:02,320 --> 06:02:04,200 a value on a given interval so we could 8564 06:02:04,200 --> 06:02:07,240 say uh pass in a second to time. tick 8565 06:02:07,240 --> 06:02:10,160 and we would get back a channel um that 8566 06:02:10,160 --> 06:02:12,920 receives a value once per second pretty 8567 06:02:12,920 --> 06:02:15,200 cool for like rate limiting doing 8568 06:02:15,200 --> 06:02:19,080 something on a set interval um time. 8569 06:02:19,080 --> 06:02:21,920 after sends a single value after the 8570 06:02:21,920 --> 06:02:23,878 specified time has passed so if we 8571 06:02:23,878 --> 06:02:26,280 created a new Channel with time. after 8572 06:02:26,280 --> 06:02:28,638 and passed in one second then one value 8573 06:02:28,638 --> 06:02:30,478 would come across after a second had 8574 06:02:30,478 --> 06:02:32,200 passed and then the channel would be 8575 06:02:32,200 --> 06:02:36,200 closed um time dos sleep just blocks for 8576 06:02:36,200 --> 06:02:37,638 the specified amount of time in fact I 8577 06:02:37,638 --> 06:02:39,638 think we've kind of seen it around um so 8578 06:02:39,638 --> 06:02:42,000 far in the course and then we have read 8579 06:02:42,000 --> 06:02:44,120 only and write only channels and these 8580 06:02:44,120 --> 06:02:46,240 are pretty cool from like a type safety 8581 06:02:46,240 --> 06:02:47,920 standpoint uh basically we can take a 8582 06:02:47,920 --> 06:02:50,160 channel and we can pass it into a 8583 06:02:50,160 --> 06:02:52,478 function but specify that within the 8584 06:02:52,478 --> 06:02:55,120 function we are just going to read from 8585 06:02:55,120 --> 06:02:57,360 it so then within the function uh the 8586 06:02:57,360 --> 06:02:59,240 compiler will not allow us to write to 8587 06:02:59,240 --> 06:03:00,920 it so this is a great way to kind of 8588 06:03:00,920 --> 06:03:03,360 keep uh go routine safe in terms of 8589 06:03:03,360 --> 06:03:05,280 which functions are readers of channels 8590 06:03:05,280 --> 06:03:06,760 and which fun fun are writers of 8591 06:03:06,760 --> 06:03:08,840 channels um and we can do the same thing 8592 06:03:08,840 --> 06:03:11,600 with writers by using this syntax here 8593 06:03:11,600 --> 06:03:13,400 so readers read out of the channel 8594 06:03:13,400 --> 06:03:15,280 writers right into the channel the 8595 06:03:15,280 --> 06:03:16,958 assignment says like all good backed 8596 06:03:16,958 --> 06:03:18,638 Engineers we frequently save backup 8597 06:03:18,638 --> 06:03:21,520 snapshots of the maleo database complete 8598 06:03:21,520 --> 06:03:24,040 the save backups function okay it should 8599 06:03:24,040 --> 06:03:26,760 read values from the snapshot ticker and 8600 06:03:26,760 --> 06:03:29,440 save after channels simultaneously okay 8601 06:03:29,440 --> 06:03:31,040 so the ticker and the save after these 8602 06:03:31,040 --> 06:03:34,320 are channels that are created down 8603 06:03:34,320 --> 06:03:37,478 here us those standard Library functions 8604 06:03:37,478 --> 06:03:38,718 that we just talked 8605 06:03:38,718 --> 06:03:43,400 about okay so we need to use a select 8606 06:03:43,400 --> 06:03:45,760 statement it looks like read values 8607 06:03:45,760 --> 06:03:47,920 continuously so I'm going to use a for 8608 06:03:47,920 --> 06:03:51,878 Loop and a select 8609 06:03:51,878 --> 06:03:54,280 statement if a value is received from 8610 06:03:54,280 --> 06:03:57,680 snapshot ticker call take snapshot okay 8611 06:03:57,680 --> 06:04:03,360 so case Val okay we want to read out of 8612 06:04:03,360 --> 06:04:07,240 a snapshot ticker 8613 06:04:08,878 --> 06:04:10,798 um do we actually do we care about the 8614 06:04:10,798 --> 06:04:13,798 channel being closed let's see saved 8615 06:04:13,798 --> 06:04:15,638 after no actually we don't so we just 8616 06:04:15,638 --> 06:04:18,280 need the value from snapshot 8617 06:04:18,280 --> 06:04:20,120 ticker oh and we don't even care about 8618 06:04:20,120 --> 06:04:21,958 what the value is so we can just 8619 06:04:21,958 --> 06:04:26,878 completely ignore the value um call take 8620 06:04:26,878 --> 06:04:29,280 snapshot 8621 06:04:29,280 --> 06:04:34,120 okay if the values saved after so 8622 06:04:34,120 --> 06:04:37,638 case save 8623 06:04:37,680 --> 06:04:41,200 after call Save 8624 06:04:41,200 --> 06:04:43,478 snapshot and return from the function 8625 06:04:43,478 --> 06:04:46,040 because we're done okay so again we 8626 06:04:46,040 --> 06:04:47,280 don't need to return anything from this 8627 06:04:47,280 --> 06:04:49,680 function doesn't have any return values 8628 06:04:49,680 --> 06:04:52,120 if neither channel has a value ready 8629 06:04:52,120 --> 06:04:56,718 call wait for data okay so 8630 06:04:56,840 --> 06:05:00,360 default wait for 8631 06:05:00,360 --> 06:05:03,478 data and then sleep for 500 milliseconds 8632 06:05:03,478 --> 06:05:07,478 so time do sleep 8633 06:05:07,478 --> 06:05:10,040 time. 8634 06:05:10,040 --> 06:05:12,558 millisecond time 8635 06:05:12,558 --> 06:05:14,200 500 8636 06:05:14,200 --> 06:05:16,240 okay this is looking good so we've got 8637 06:05:16,240 --> 06:05:17,878 this infinite for Loop we'll we're 8638 06:05:17,878 --> 06:05:20,718 looking for values um that are coming 8639 06:05:20,718 --> 06:05:23,520 across these channels anytime a snapshot 8640 06:05:23,520 --> 06:05:26,080 should be taken we take it anytime um 8641 06:05:26,080 --> 06:05:28,718 this save after Channel passes us a 8642 06:05:28,718 --> 06:05:31,280 value we will save the snapshot and exit 8643 06:05:31,280 --> 06:05:34,718 the function otherwise we'll wait for 8644 06:05:34,718 --> 06:05:37,200 data whatever that does and sleep for 8645 06:05:37,200 --> 06:05:38,878 500 milliseconds in fact I'm curious 8646 06:05:38,878 --> 06:05:40,440 what does wait for day to do okay so all 8647 06:05:40,440 --> 06:05:43,200 these do um is kind of Print Different 8648 06:05:43,200 --> 06:05:46,520 messages so let's go ahead and run 8649 06:05:49,600 --> 06:05:52,360 that okay cool so nothing to do waiting 8650 06:05:52,360 --> 06:05:54,520 nothing to do waiting right so every 500 8651 06:05:54,520 --> 06:05:56,160 milliseconds we're kind of logging out 8652 06:05:56,160 --> 06:05:57,478 that we are waiting we're waiting for 8653 06:05:57,478 --> 06:06:00,680 things to to do um taking back backups 8654 06:06:00,680 --> 06:06:03,600 taking backups and um finally saving the 8655 06:06:03,600 --> 06:06:05,280 backups at the end cool let's submit 8656 06:06:05,280 --> 06:06:08,920 this looks correct to me Dave Cheney is 8657 06:06:08,920 --> 06:06:11,718 a fantastic author and contributor to 8658 06:06:11,718 --> 06:06:13,478 the go programming language and the go 8659 06:06:13,478 --> 06:06:15,638 ecosystem um and he has this awesome 8660 06:06:15,638 --> 06:06:16,760 article that I would definitely 8661 06:06:16,760 --> 06:06:18,320 recommend checking out it's called 8662 06:06:18,320 --> 06:06:20,440 Channel axioms um I've kind of 8663 06:06:20,440 --> 06:06:22,600 summarized it here and we're going to 8664 06:06:22,600 --> 06:06:25,000 talk about a few key points so the first 8665 06:06:25,000 --> 06:06:27,920 is that Ascend to a nil Channel blocks 8666 06:06:27,920 --> 06:06:31,040 forever so the zero value for a channel 8667 06:06:31,040 --> 06:06:33,000 is nil if you don't use the make 8668 06:06:33,000 --> 06:06:34,840 function to initialize a channel then 8669 06:06:34,840 --> 06:06:37,080 the Channel's value is just nil and if 8670 06:06:37,080 --> 06:06:40,360 you try to send on a nil Channel your 8671 06:06:40,360 --> 06:06:42,798 code's just going to block forever 8672 06:06:42,798 --> 06:06:45,958 similarly a receive from a nil channel 8673 06:06:45,958 --> 06:06:48,440 will just block forever now this one's a 8674 06:06:48,440 --> 06:06:51,320 lot more dangerous trying to send on a 8675 06:06:51,320 --> 06:06:54,280 closed Channel panics so you need to be 8676 06:06:54,280 --> 06:06:55,878 really careful and make sure you're only 8677 06:06:55,878 --> 06:06:58,958 closing channels from the go routine or 8678 06:06:58,958 --> 06:07:00,440 the function that's writing to the 8679 06:07:00,440 --> 06:07:02,440 channel so that you can be sure you'll 8680 06:07:02,440 --> 06:07:04,240 never try to write to that closed 8681 06:07:04,240 --> 06:07:06,600 Channel again and then then a receive 8682 06:07:06,600 --> 06:07:09,200 from a closed Channel Returns the zero 8683 06:07:09,200 --> 06:07:11,000 value immediately so if you're trying to 8684 06:07:11,000 --> 06:07:12,798 pull data out of a channel and it's 8685 06:07:12,798 --> 06:07:14,478 already closed you'll just get the zero 8686 06:07:14,478 --> 06:07:16,600 value and we've already seen how you can 8687 06:07:16,600 --> 06:07:18,400 also kind of optionally check for that 8688 06:07:18,400 --> 06:07:20,760 okay value uh which will be returned as 8689 06:07:20,760 --> 06:07:23,360 false so what happens when you read from 8690 06:07:23,360 --> 06:07:26,320 a nil's channel uh the receiver will 8691 06:07:26,320 --> 06:07:29,040 block forever and what happens when you 8692 06:07:29,040 --> 06:07:32,160 send to a closed channel uh you'll get a 8693 06:07:32,160 --> 06:07:34,558 panic and you never really want to panic 8694 06:07:34,558 --> 06:07:36,798 and go that's almost always indicative 8695 06:07:36,798 --> 06:07:40,080 of a bug so channels are one tool that 8696 06:07:40,080 --> 06:07:42,360 we have in go to sort of synchronize 8697 06:07:42,360 --> 06:07:45,320 State across different go routines right 8698 06:07:45,320 --> 06:07:47,478 we can send data from one go routine to 8699 06:07:47,478 --> 06:07:50,200 another safely mutexes are another 8700 06:07:50,200 --> 06:07:52,240 builtin primitive well rather they're 8701 06:07:52,240 --> 06:07:53,718 not built into the language but they're 8702 06:07:53,718 --> 06:07:56,240 built into the standard library and they 8703 06:07:56,240 --> 06:07:58,878 allow us to also sort of communicate or 8704 06:07:58,878 --> 06:08:02,520 share data between two go routines 8705 06:08:02,520 --> 06:08:05,878 mutexes work by locking access to 8706 06:08:05,878 --> 06:08:08,440 protected resources so that only one go 8707 06:08:08,440 --> 06:08:10,840 routine can access that resource at a 8708 06:08:10,840 --> 06:08:15,000 time so the sync. mutex type is exposed 8709 06:08:15,000 --> 06:08:17,000 by the standard library and basically 8710 06:08:17,000 --> 06:08:18,360 the way it works is you create a new 8711 06:08:18,360 --> 06:08:20,718 mutex and then you share it across many 8712 06:08:20,718 --> 06:08:24,760 different go routines and then you wrap 8713 06:08:24,760 --> 06:08:27,280 whatever code that that is dangerous or 8714 06:08:27,280 --> 06:08:29,558 whatever resource that is dangerous um 8715 06:08:29,558 --> 06:08:32,040 that you never want two go routines at 8716 06:08:32,040 --> 06:08:34,680 the same time kind of getting access to 8717 06:08:34,680 --> 06:08:37,718 you wrap them in a call to lock and 8718 06:08:37,718 --> 06:08:39,400 unlock so for example in this function 8719 06:08:39,400 --> 06:08:42,320 we have this protected function and it 8720 06:08:42,320 --> 06:08:44,600 calls mx. lock at the top of the 8721 06:08:44,600 --> 06:08:48,440 function and then it defers an unlock 8722 06:08:48,440 --> 06:08:50,718 and what this means is when one go 8723 06:08:50,718 --> 06:08:53,718 routine calls this protected function um 8724 06:08:53,718 --> 06:08:56,200 if it's the first call to this protected 8725 06:08:56,200 --> 06:08:58,558 function then this mx. loock will lock 8726 06:08:58,558 --> 06:09:01,120 the mutex for this go routine and it 8727 06:09:01,120 --> 06:09:02,718 will be able to move on and kind of 8728 06:09:02,718 --> 06:09:04,120 complete the rest of the function and 8729 06:09:04,120 --> 06:09:07,680 then call uh m tex. unlock every other 8730 06:09:07,680 --> 06:09:10,680 go routine that calls this function 8731 06:09:10,680 --> 06:09:12,638 right on this shared mutex will actually 8732 06:09:12,638 --> 06:09:16,798 block at the mx. loock function call 8733 06:09:16,798 --> 06:09:18,680 because the mutex is locked by another 8734 06:09:18,680 --> 06:09:21,760 go routine so mutex stands for Mutual 8735 06:09:21,760 --> 06:09:24,520 exclusion because it excludes every go 8736 06:09:24,520 --> 06:09:26,240 routine except one except for the one 8737 06:09:26,240 --> 06:09:28,320 that holds the lock and once that first 8738 06:09:28,320 --> 06:09:31,040 one actually unlocks the mutex then one 8739 06:09:31,040 --> 06:09:32,878 other go routine is able to pick up the 8740 06:09:32,878 --> 06:09:36,080 lock um execute its protected code 8741 06:09:36,080 --> 06:09:38,040 and move on from there so it's a way to 8742 06:09:38,040 --> 06:09:40,400 take some dangerous resource and sort of 8743 06:09:40,400 --> 06:09:42,000 share it across many different go 8744 06:09:42,000 --> 06:09:44,798 routines uh safely there are a couple of 8745 06:09:44,798 --> 06:09:47,040 different reasons why you would want to 8746 06:09:47,040 --> 06:09:48,958 protect a resource and only allow a 8747 06:09:48,958 --> 06:09:51,360 single go routine to kind of work on 8748 06:09:51,360 --> 06:09:53,638 that resource at a time but one super 8749 06:09:53,638 --> 06:09:57,040 common one is Maps so maps are not 8750 06:09:57,040 --> 06:09:59,360 thread safe in go if two different go 8751 06:09:59,360 --> 06:10:01,840 routines or trying to read from and 8752 06:10:01,840 --> 06:10:04,320 write to the same map uh go will 8753 06:10:04,320 --> 06:10:05,958 actually panic 8754 06:10:05,958 --> 06:10:07,840 uh because that has a very high 8755 06:10:07,840 --> 06:10:09,798 likelihood of causing a race condition 8756 06:10:09,798 --> 06:10:11,400 and if you're wondering what a race 8757 06:10:11,400 --> 06:10:13,638 condition is a race condition is kind of 8758 06:10:13,638 --> 06:10:15,200 what it sounds like it's when two 8759 06:10:15,200 --> 06:10:18,360 different go routines effectively racing 8760 06:10:18,360 --> 06:10:20,920 uh to get access to a specific resource 8761 06:10:20,920 --> 06:10:23,520 so imagine a case where we have a count 8762 06:10:23,520 --> 06:10:25,280 variable and it's set equal to maybe 8763 06:10:25,280 --> 06:10:27,360 five and you have one go routine that 8764 06:10:27,360 --> 06:10:29,360 reads that count variable and saves it 8765 06:10:29,360 --> 06:10:32,320 into say another variable my count right 8766 06:10:32,320 --> 06:10:34,400 and then maybe doubles it and then saves 8767 06:10:34,400 --> 06:10:37,160 the doubled value back into count well 8768 06:10:37,160 --> 06:10:39,798 what if we have another uh thread of 8769 06:10:39,798 --> 06:10:42,000 execution doing the same thing if they 8770 06:10:42,000 --> 06:10:44,360 both read count let's say they both read 8771 06:10:44,360 --> 06:10:46,000 five 8772 06:10:46,000 --> 06:10:49,958 double five so now they both store 25 8773 06:10:49,958 --> 06:10:52,520 and they both go to write 25 back into 8774 06:10:52,520 --> 06:10:56,120 the variable all you did was double five 8775 06:10:56,120 --> 06:10:58,840 once where you were probably expecting 8776 06:10:58,840 --> 06:11:01,040 to have two different threads doubling 8777 06:11:01,040 --> 06:11:02,840 the variable so you probably were 8778 06:11:02,840 --> 06:11:05,360 expecting for it to go 5 to 25 and then 8779 06:11:05,360 --> 06:11:09,680 double again 25 s 625 I think um the 8780 06:11:09,680 --> 06:11:12,200 point is depending on exactly how those 8781 06:11:12,200 --> 06:11:14,240 operations are threaded into the CPU 8782 06:11:14,240 --> 06:11:16,680 you'll actually get different Behavior 8783 06:11:16,680 --> 06:11:19,878 so race conditions are awful to debug 8784 06:11:19,878 --> 06:11:23,120 and mutexes allow us to lock access to 8785 06:11:23,120 --> 06:11:24,360 those protected variables so we could 8786 06:11:24,360 --> 06:11:27,840 wrap that count variable in a mutex to 8787 06:11:27,840 --> 06:11:30,558 avoid it being accessed at the same time 8788 06:11:30,558 --> 06:11:33,360 by different go routines so this should 8789 06:11:33,360 --> 06:11:35,280 make a lot more sense once we write some 8790 06:11:35,280 --> 06:11:37,558 code the assignment says we send emails 8791 06:11:37,558 --> 06:11:39,360 across many different go routines at 8792 06:11:39,360 --> 06:11:41,798 maleo to keep track of how many we've 8793 06:11:41,798 --> 06:11:43,920 sent to a given email address we use an 8794 06:11:43,920 --> 06:11:46,520 in-memory map Okay so we've got this 8795 06:11:46,520 --> 06:11:49,680 counts map stored within a safe counter 8796 06:11:49,680 --> 06:11:52,080 struct the map is of string to integer 8797 06:11:52,080 --> 06:11:54,360 and then we've got a pointer to a mutex 8798 06:11:54,360 --> 06:11:56,200 uh that we're sharing across all these 8799 06:11:56,200 --> 06:11:59,040 different go routines um our safe 8800 06:11:59,040 --> 06:12:01,680 counter struct is unsafe update the 8801 06:12:01,680 --> 06:12:04,558 increment and the value methods so they 8802 06:12:04,558 --> 06:12:06,320 utilize the safe counters mutex to 8803 06:12:06,320 --> 06:12:08,400 ensure that the map is not accessed by 8804 06:12:08,400 --> 06:12:11,840 multiple go routines at the same time 8805 06:12:11,840 --> 06:12:14,080 okay so we've got the safe counter and 8806 06:12:14,080 --> 06:12:15,920 it looks like it's going to be kind of 8807 06:12:15,920 --> 06:12:18,958 copied across different go routines so 8808 06:12:18,958 --> 06:12:20,638 we create one instance of the safe 8809 06:12:20,638 --> 06:12:23,040 counter um it's getting passed into this 8810 06:12:23,040 --> 06:12:25,320 test function and then we've got this go 8811 06:12:25,320 --> 06:12:27,478 routine um it looks like we're spawning 8812 06:12:27,478 --> 06:12:30,920 go routines in a for Loop and then uh 8813 06:12:30,920 --> 06:12:32,798 and then using that safe counter right 8814 06:12:32,798 --> 06:12:34,680 so increment is being called many 8815 06:12:34,680 --> 06:12:37,120 different times across many different uh 8816 06:12:37,120 --> 06:12:39,440 threads of execution and that is not 8817 06:12:39,440 --> 06:12:42,760 safe cool um so let's see what happens 8818 06:12:42,760 --> 06:12:46,000 if I run the code right 8819 06:12:46,360 --> 06:12:49,920 now Jill has three emails John has 8820 06:12:49,920 --> 06:12:52,520 four and if I look down into the tests 8821 06:12:52,520 --> 06:12:55,798 like that is wildly inaccurate right so 8822 06:12:55,798 --> 06:12:58,000 it it kind of looks like what's 8823 06:12:58,000 --> 06:13:00,120 happening is is like the example I 8824 06:13:00,120 --> 06:13:02,520 described where maybe you're multiplying 8825 06:13:02,520 --> 06:13:04,798 numbers together at the same time so you 8826 06:13:04,798 --> 06:13:06,680 kind of end up with a smaller number cuz 8827 06:13:06,680 --> 06:13:07,920 everyone's doing it at the same time 8828 06:13:07,920 --> 06:13:09,440 then saving the variable back it kind of 8829 06:13:09,440 --> 06:13:11,120 looks like that's what's happening we're 8830 06:13:11,120 --> 06:13:13,320 getting these tiny results cuz all of 8831 06:13:13,320 --> 06:13:14,600 these different go routines are 8832 06:13:14,600 --> 06:13:17,680 incrementing uh the number at the same 8833 06:13:17,680 --> 06:13:23,520 time okay so we need to lock this 8834 06:13:23,520 --> 06:13:25,040 down 8835 06:13:25,040 --> 06:13:27,120 sc. 8836 06:13:27,120 --> 06:13:30,240 m.m. loock so lock 8837 06:13:30,240 --> 06:13:36,000 the the mutex and then defer the unlock 8838 06:13:36,440 --> 06:13:38,040 it's important to understand that we 8839 06:13:38,040 --> 06:13:40,958 could do this and it would be the 8840 06:13:40,958 --> 06:13:43,920 same um right we lock we do the 8841 06:13:43,920 --> 06:13:46,718 dangerous thing and then we unlock um 8842 06:13:46,718 --> 06:13:49,160 but this is the 8843 06:13:49,160 --> 06:13:51,240 preferred the preferred way kind of the 8844 06:13:51,240 --> 06:13:53,798 idiomatic go way to do it um it just 8845 06:13:53,798 --> 06:13:55,680 it's just a little safer right if we add 8846 06:13:55,680 --> 06:13:57,920 multiple Returns the defer will never 8847 06:13:57,920 --> 06:14:00,718 not execute so um that's how we're going 8848 06:14:00,718 --> 06:14:03,798 to do it and then we also need to lock 8849 06:14:03,798 --> 06:14:06,520 um on the Val function because reading 8850 06:14:06,520 --> 06:14:08,958 um and writing at the same time is also 8851 06:14:08,958 --> 06:14:11,878 dangerous cool let's run that see if we 8852 06:14:11,878 --> 06:14:14,520 get some bigger numbers in our 8853 06:14:14,520 --> 06:14:17,840 counts notice it's taking a lot longer 8854 06:14:17,840 --> 06:14:19,798 to run and and that's because we're 8855 06:14:19,798 --> 06:14:22,440 locking and unlocking so every thread 8856 06:14:22,440 --> 06:14:25,040 has to kind of go one after the other so 8857 06:14:25,040 --> 06:14:28,200 it slows it down um but it's a lot safer 8858 06:14:28,200 --> 06:14:31,200 so we get these accurate counts let's go 8859 06:14:31,200 --> 06:14:32,840 ahead and submit 8860 06:14:32,840 --> 06:14:35,840 that so as we discussed am mutex is 8861 06:14:35,840 --> 06:14:37,558 called a mutex because it's short for 8862 06:14:37,558 --> 06:14:41,040 Mutual exclusion and the conventional 8863 06:14:41,040 --> 06:14:44,600 name for a mutex is um mutex or 8864 06:14:44,600 --> 06:14:46,558 sometimes it's abbreviated to MX 8865 06:14:46,558 --> 06:14:49,958 personally I use MX a lot so to answer 8866 06:14:49,958 --> 06:14:51,840 the question what does it refer to it's 8867 06:14:51,840 --> 06:14:53,600 going to be mutual exclusion the next 8868 06:14:53,600 --> 06:14:55,718 question is how many threads or go 8869 06:14:55,718 --> 06:14:58,558 routines can lock a mutex at once or at 8870 06:14:58,558 --> 06:15:03,160 the same time the answer is one right if 8871 06:15:03,160 --> 06:15:05,040 any more could lock it at the same time 8872 06:15:05,040 --> 06:15:07,718 time it wouldn't be very useful the next 8873 06:15:07,718 --> 06:15:10,520 question is why would you use a mutex to 8874 06:15:10,520 --> 06:15:12,000 safely access a data structure 8875 06:15:12,000 --> 06:15:14,200 concurrently to stop other packages from 8876 06:15:14,200 --> 06:15:16,200 using my code to protect data from 8877 06:15:16,200 --> 06:15:18,320 network access or to encapsulate private 8878 06:15:18,320 --> 06:15:20,440 data members of a struct it's going to 8879 06:15:20,440 --> 06:15:23,440 be to safely Access Data 8880 06:15:23,440 --> 06:15:26,200 concurrently time to talk about another 8881 06:15:26,200 --> 06:15:29,040 type of mutex so we've already covered 8882 06:15:29,040 --> 06:15:30,440 pretty much all of the functionality you 8883 06:15:30,440 --> 06:15:32,958 need to know about the sync. mutex type 8884 06:15:32,958 --> 06:15:35,000 but there's another type there is a 8885 06:15:35,000 --> 06:15:40,200 sync. RW mutex or sync. readr mutex so 8886 06:15:40,200 --> 06:15:43,558 the sync. readr mutex has a little more 8887 06:15:43,558 --> 06:15:45,638 functionality um it has the same lock 8888 06:15:45,638 --> 06:15:48,000 and unlock methods and works exactly the 8889 06:15:48,000 --> 06:15:50,478 same way as a normal mutex but 8890 06:15:50,478 --> 06:15:52,798 additionally it has two more methods 8891 06:15:52,798 --> 06:15:55,718 rlock and R unlock so the reason you 8892 06:15:55,718 --> 06:15:58,638 would use a read write mutex is because 8893 06:15:58,638 --> 06:16:00,840 it allows you to have multiple readers 8894 06:16:00,840 --> 06:16:03,120 at the same time for example it's 8895 06:16:03,120 --> 06:16:06,160 actually safe to read for from a map on 8896 06:16:06,160 --> 06:16:08,360 multiple go routines at the same time as 8897 06:16:08,360 --> 06:16:10,160 long as you're not reading and writing 8898 06:16:10,160 --> 06:16:12,558 at the same time or writing and writing 8899 06:16:12,558 --> 06:16:14,360 at the same time writing is the 8900 06:16:14,360 --> 06:16:16,840 dangerous operation so the way this 8901 06:16:16,840 --> 06:16:20,240 works is if the mutex is locked like 8902 06:16:20,240 --> 06:16:23,520 with the do loock method then no other 8903 06:16:23,520 --> 06:16:28,320 go routines can lock or arlock the mutex 8904 06:16:28,320 --> 06:16:31,600 however if the mutex is just are locked 8905 06:16:31,600 --> 06:16:35,920 then other mutexes can still our locket 8906 06:16:35,920 --> 06:16:38,160 so you can get multiple readers but you 8907 06:16:38,160 --> 06:16:41,040 can't get readers and writers or writers 8908 06:16:41,040 --> 06:16:43,718 and writers it just allows many threads 8909 06:16:43,718 --> 06:16:46,680 to concurrently read so what this does 8910 06:16:46,680 --> 06:16:48,798 is if you have a program with a shared 8911 06:16:48,798 --> 06:16:51,200 resource where most of the threads are 8912 06:16:51,200 --> 06:16:52,680 interested with reading the shared 8913 06:16:52,680 --> 06:16:54,760 resource and you only have a few writers 8914 06:16:54,760 --> 06:16:57,320 you can make your code a lot faster by 8915 06:16:57,320 --> 06:16:59,280 using a read write mutex and allowing 8916 06:16:59,280 --> 06:17:01,080 multiple readers at the same time your 8917 06:17:01,080 --> 06:17:03,360 code will move faster and have fewer 8918 06:17:03,360 --> 06:17:05,360 locks slowing down 8919 06:17:05,360 --> 06:17:07,680 um and synchronizing your application so 8920 06:17:07,680 --> 06:17:09,600 on to the assignment it says let's 8921 06:17:09,600 --> 06:17:11,160 update our same code from the last 8922 06:17:11,160 --> 06:17:12,718 assignment but this time we can speed it 8923 06:17:12,718 --> 06:17:14,400 up by allowing readers to be read from 8924 06:17:14,400 --> 06:17:16,798 the map concurrently update The Vow 8925 06:17:16,798 --> 06:17:18,600 method to only lock the mutex for 8926 06:17:18,600 --> 06:17:20,558 reading notice that if you run the code 8927 06:17:20,558 --> 06:17:22,320 with a right lock it will block forever 8928 06:17:22,320 --> 06:17:24,080 Okay cool so if I run try to run it 8929 06:17:24,080 --> 06:17:26,878 right now um it's going to have issues 8930 06:17:26,878 --> 06:17:31,600 because I believe it is are locked um by 8931 06:17:31,600 --> 06:17:34,040 the test Suite out of the gate so that's 8932 06:17:34,040 --> 06:17:37,040 a problem um we can fix 8933 06:17:37,040 --> 06:17:43,000 it by changing those to rlock and R 8934 06:17:47,240 --> 06:17:49,440 unlock perfect looks good to me I'm 8935 06:17:49,440 --> 06:17:52,760 going to go ahead and submit that so a 8936 06:17:52,760 --> 06:17:55,120 quick review on read write mutexes how 8937 06:17:55,120 --> 06:17:57,840 many writers can access an RW mutex at 8938 06:17:57,840 --> 06:18:00,440 once or at the same time uh the answer 8939 06:18:00,440 --> 06:18:03,600 is one and how many readers can access 8940 06:18:03,600 --> 06:18:05,958 an RW mutex at once it's going to be 8941 06:18:05,958 --> 06:18:08,320 infinite there is no limit the next 8942 06:18:08,320 --> 06:18:10,360 question is can readers and writers use 8943 06:18:10,360 --> 06:18:13,840 RW mutexes at the same time the answer 8944 06:18:13,840 --> 06:18:16,400 is still no right no one can use the 8945 06:18:16,400 --> 06:18:19,478 mutex if it's being written to generics 8946 06:18:19,478 --> 06:18:21,798 are an amazing new feature in the go 8947 06:18:21,798 --> 06:18:24,040 programming language at least they are 8948 06:18:24,040 --> 06:18:26,240 new as of the time of this recording 8949 06:18:26,240 --> 06:18:28,680 we're on version 1.20 now and generics 8950 06:18:28,680 --> 06:18:31,320 were just released in 1.18 and they were 8951 06:18:31,320 --> 06:18:33,280 one of the most widely requested 8952 06:18:33,280 --> 06:18:36,400 features by go developers so let's talk 8953 06:18:36,400 --> 06:18:38,280 about what generics are and why they're 8954 06:18:38,280 --> 06:18:41,878 so useful let's take a look at this code 8955 06:18:41,878 --> 06:18:44,400 here we have a function called split in 8956 06:18:44,400 --> 06:18:46,878 slice so it takes a slice of ins and it 8957 06:18:46,878 --> 06:18:50,200 splits it into two smaller slices of 8958 06:18:50,200 --> 06:18:52,120 integers it effectively just splits the 8959 06:18:52,120 --> 06:18:56,160 slice in half and returns two new slices 8960 06:18:56,160 --> 06:18:57,718 the really interesting thing about this 8961 06:18:57,718 --> 06:18:59,000 function is that if you take a look at 8962 06:18:59,000 --> 06:19:01,680 the function body it doesn't actually 8963 06:19:01,680 --> 06:19:04,520 care that this is a slice of ins it 8964 06:19:04,520 --> 06:19:05,958 could be a slice of strings or a slice 8965 06:19:05,958 --> 06:19:07,760 of booleans the logic in the function 8966 06:19:07,760 --> 06:19:09,600 body would be the same right calculate 8967 06:19:09,600 --> 06:19:11,840 um kind of the midpoint of the slice and 8968 06:19:11,840 --> 06:19:14,080 return two new slices um with all the 8969 06:19:14,080 --> 06:19:17,200 values up to that midpoint the annoying 8970 06:19:17,200 --> 06:19:19,638 thing is that prior to generics in 8971 06:19:19,638 --> 06:19:22,360 version 1.18 if we wanted to split a 8972 06:19:22,360 --> 06:19:23,760 slice of strings we would actually need 8973 06:19:23,760 --> 06:19:26,840 to write an entirely separate function 8974 06:19:26,840 --> 06:19:29,440 because in go we have static typing and 8975 06:19:29,440 --> 06:19:32,040 we need to tell the compiler what type 8976 06:19:32,040 --> 06:19:35,280 of slice it is that we are splitting now 8977 06:19:35,280 --> 06:19:38,000 it is true that prior to generics you 8978 06:19:38,000 --> 06:19:40,080 could write a function that takes a 8979 06:19:40,080 --> 06:19:42,440 slice of the empty interface which is 8980 06:19:42,440 --> 06:19:44,400 essentially a slice of anything and then 8981 06:19:44,400 --> 06:19:47,400 returns to slices of the empty interface 8982 06:19:47,400 --> 06:19:49,080 the problem with that is that you need 8983 06:19:49,080 --> 06:19:52,040 to cast the return values back into 8984 06:19:52,040 --> 06:19:53,400 whatever they were which is kind of a 8985 06:19:53,400 --> 06:19:57,878 dangerous runtime check so generics or 8986 06:19:57,878 --> 06:20:00,400 type parameters are really just a way 8987 06:20:00,400 --> 06:20:02,080 for us to write that function with the 8988 06:20:02,080 --> 06:20:05,080 empty interface but do it in a compile 8989 06:20:05,080 --> 06:20:06,520 safe way because if you think about it 8990 06:20:06,520 --> 06:20:10,240 the compiler can know that this function 8991 06:20:10,240 --> 06:20:13,520 doesn't care about the types going in 8992 06:20:13,520 --> 06:20:16,000 but that anytime it's called the types 8993 06:20:16,000 --> 06:20:18,440 coming out will be the same as the types 8994 06:20:18,440 --> 06:20:21,240 coming in so how does it work well we 8995 06:20:21,240 --> 06:20:23,878 effectively have a new type of parameter 8996 06:20:23,878 --> 06:20:25,920 that can be passed into a function so 8997 06:20:25,920 --> 06:20:27,920 after the function's name we have these 8998 06:20:27,920 --> 06:20:30,200 optional square brackets and here we're 8999 06:20:30,200 --> 06:20:34,000 defining a new type we're calling it t 9000 06:20:34,000 --> 06:20:36,920 and we're saying it is of type any or it 9001 06:20:36,920 --> 06:20:41,400 can be anything now because we using T 9002 06:20:41,400 --> 06:20:44,280 the type parameter as both the input and 9003 06:20:44,280 --> 06:20:46,638 the output we're telling the go compiler 9004 06:20:46,638 --> 06:20:49,440 hey whatever I pass into this function 9005 06:20:49,440 --> 06:20:50,920 that's what I'm expecting to get back 9006 06:20:50,920 --> 06:20:52,558 out right if I pass in a slice of 9007 06:20:52,558 --> 06:20:55,638 integers I expect to get out two slices 9008 06:20:55,638 --> 06:20:58,240 of integers so now if we take a look at 9009 06:20:58,240 --> 06:21:01,120 how the code is actually used right how 9010 06:21:01,120 --> 06:21:03,120 the function is called we can use the 9011 06:21:03,120 --> 06:21:06,120 split any slice function give it a slice 9012 06:21:06,120 --> 06:21:08,638 of integers and we'll get back two 9013 06:21:08,638 --> 06:21:11,080 slices of integers everything is type 9014 06:21:11,080 --> 06:21:14,120 safe so in a nutshell the reason to use 9015 06:21:14,120 --> 06:21:17,160 generics is to dry up our code right dry 9016 06:21:17,160 --> 06:21:19,320 is just an acronym for don't repeat 9017 06:21:19,320 --> 06:21:21,120 yourself it's a way of writing code uh 9018 06:21:21,120 --> 06:21:23,638 that can be reused uh more easily so 9019 06:21:23,638 --> 06:21:25,520 instead of having to write two nearly 9020 06:21:25,520 --> 06:21:27,520 identical functions just to deal with 9021 06:21:27,520 --> 06:21:30,120 two separate types of slices we can now 9022 06:21:30,120 --> 06:21:33,200 write a typ safe function once and reuse 9023 06:21:33,200 --> 06:21:35,320 it throughout our application so let's 9024 06:21:35,320 --> 06:21:37,200 Jump Right In the assignment says at 9025 06:21:37,200 --> 06:21:39,240 maleo we often store all of the emails 9026 06:21:39,240 --> 06:21:41,680 of a given email campaign in memory as a 9027 06:21:41,680 --> 06:21:43,600 slice we store payments for a single 9028 06:21:43,600 --> 06:21:45,000 user in the same way so those are two 9029 06:21:45,000 --> 06:21:46,878 very different things right emails and 9030 06:21:46,878 --> 06:21:49,958 payments complete the get last function 9031 06:21:49,958 --> 06:21:51,478 it should be a generic function that 9032 06:21:51,478 --> 06:21:53,680 Returns the last element from a slice no 9033 06:21:53,680 --> 06:21:55,440 matter the type stored in the slice if 9034 06:21:55,440 --> 06:21:56,760 the slice is empty it should return the 9035 06:21:56,760 --> 06:21:58,718 zero value of the type okay cool let's 9036 06:21:58,718 --> 06:22:00,638 get started okay so we can kind of use 9037 06:22:00,638 --> 06:22:03,080 this syntax as a guide so we're going to 9038 06:22:03,080 --> 06:22:05,958 need um to specify type it can be 9039 06:22:05,958 --> 06:22:08,440 anything like the assignment said and 9040 06:22:08,440 --> 06:22:10,478 we're going to take as input a slice of 9041 06:22:10,478 --> 06:22:14,400 that type and return one element of that 9042 06:22:14,400 --> 06:22:17,520 type okay now it says um we need to 9043 06:22:17,520 --> 06:22:20,718 return the last element from a slice so 9044 06:22:20,718 --> 06:22:22,280 uh we need to slice the slice 9045 06:22:22,280 --> 06:22:23,878 essentially check its length right so we 9046 06:22:23,878 --> 06:22:29,920 can say um if the length of s is zero so 9047 06:22:29,920 --> 06:22:31,000 if there's nothing in the slice we're 9048 06:22:31,000 --> 06:22:32,840 going to have to just 9049 06:22:32,840 --> 06:22:38,160 return uh the m empty type of T which 9050 06:22:38,160 --> 06:22:40,200 down here it says we can create uh we 9051 06:22:40,200 --> 06:22:42,040 can create a new empty variable like 9052 06:22:42,040 --> 06:22:43,718 this so we'll just 9053 06:22:43,718 --> 06:22:45,958 do 9054 06:22:45,958 --> 06:22:50,160 bar zero Val and then we'll just return 9055 06:22:50,160 --> 06:22:52,320 it okay cool so if the slice is empty 9056 06:22:52,320 --> 06:22:55,638 we'll return the the zero value um 9057 06:22:55,638 --> 06:22:58,120 otherwise we'll 9058 06:22:58,120 --> 06:23:00,360 return S 9059 06:23:00,360 --> 06:23:05,400 at the length of s minus one right okay 9060 06:23:05,400 --> 06:23:07,240 so if there's nothing in the slice we'll 9061 06:23:07,240 --> 06:23:09,718 return the Z zero value otherwise we'll 9062 06:23:09,718 --> 06:23:11,878 return the element in the last index and 9063 06:23:11,878 --> 06:23:13,280 the reason we have to do this guard 9064 06:23:13,280 --> 06:23:14,760 Clause is because otherwise this would 9065 06:23:14,760 --> 06:23:16,878 be an unsafe operation we'd get an index 9066 06:23:16,878 --> 06:23:19,760 out of Bounce error uh if we tried to do 9067 06:23:19,760 --> 06:23:22,478 this operation on a slice of zero length 9068 06:23:22,478 --> 06:23:25,400 so let's go ahead and run 9069 06:23:25,400 --> 06:23:28,360 it and it looks 9070 06:23:28,360 --> 06:23:31,000 like okay so the test case with a zero 9071 06:23:31,000 --> 06:23:33,478 length slice returns an empty struct 9072 06:23:33,478 --> 06:23:35,638 that looks correct to me me getting last 9073 06:23:35,638 --> 06:23:38,040 email from a slice of length three 9074 06:23:38,040 --> 06:23:40,080 there's the last one looks like it 9075 06:23:40,080 --> 06:23:41,760 returned it correctly and then here we 9076 06:23:41,760 --> 06:23:43,280 have payments right so a completely 9077 06:23:43,280 --> 06:23:45,478 different type and the last one is Jane 9078 06:23:45,478 --> 06:23:48,080 example.com yep that looks correct to me 9079 06:23:48,080 --> 06:23:51,840 Margo Margo cool let's submit it so why 9080 06:23:51,840 --> 06:23:53,718 are there generics in the go programming 9081 06:23:53,718 --> 06:23:55,638 language well there's kind of three main 9082 06:23:55,638 --> 06:23:57,280 points that are important to understand 9083 06:23:57,280 --> 06:23:58,798 the first as we already covered is that 9084 06:23:58,798 --> 06:24:01,320 generics reduce repetitive code so 9085 06:24:01,320 --> 06:24:02,680 whenever we have code that doesn't 9086 06:24:02,680 --> 06:24:04,000 really care about the type or maybe it 9087 06:24:04,000 --> 06:24:06,600 only about a small superficial part of 9088 06:24:06,600 --> 06:24:09,360 the type then we can write more abstract 9089 06:24:09,360 --> 06:24:11,680 and more reusable code if we have access 9090 06:24:11,680 --> 06:24:13,718 to generics right because it keeps the 9091 06:24:13,718 --> 06:24:16,280 code compile time safe and type safe 9092 06:24:16,280 --> 06:24:18,240 before in go if we wanted to reuse code 9093 06:24:18,240 --> 06:24:20,680 we had to do sort of dangerous runtime 9094 06:24:20,680 --> 06:24:23,000 checking right casting things to empty 9095 06:24:23,000 --> 06:24:25,520 interfaces and back from empty 9096 06:24:25,520 --> 06:24:27,798 interfaces it's also important to 9097 06:24:27,798 --> 06:24:29,478 understand that generics are going to be 9098 06:24:29,478 --> 06:24:32,200 used much more frequently in libraries 9099 06:24:32,200 --> 06:24:34,718 and packages if you're say about backend 9100 06:24:34,718 --> 06:24:36,520 developer and you're building 9101 06:24:36,520 --> 06:24:38,958 applications um and not libraries or 9102 06:24:38,958 --> 06:24:40,320 packages that are intended to be used by 9103 06:24:40,320 --> 06:24:42,520 other people um You probably don't need 9104 06:24:42,520 --> 06:24:44,878 to use generics all that often which is 9105 06:24:44,878 --> 06:24:46,680 why the go programming language was able 9106 06:24:46,680 --> 06:24:48,400 to get away with not even supporting 9107 06:24:48,400 --> 06:24:51,440 them for so long now if you do work on 9108 06:24:51,440 --> 06:24:53,520 libraries or packages or maybe you're 9109 06:24:53,520 --> 06:24:55,878 even a contributor to the go standard 9110 06:24:55,878 --> 06:24:58,000 library then you probably are going to 9111 06:24:58,000 --> 06:25:00,320 use generics quite a bit more they'll 9112 06:25:00,320 --> 06:25:02,120 make it a lot easier to write more 9113 06:25:02,120 --> 06:25:04,320 abstract code that's useful uh for more 9114 06:25:04,320 --> 06:25:06,878 and more use cases the last Point that's 9115 06:25:06,878 --> 06:25:09,000 important to understand is just Why did 9116 06:25:09,000 --> 06:25:11,080 it take so long to get generics into the 9117 06:25:11,080 --> 06:25:13,718 language right they're super useful why 9118 06:25:13,718 --> 06:25:15,400 didn't we add them I don't know five 9119 06:25:15,400 --> 06:25:18,360 years ago or a decade ago and go was 9120 06:25:18,360 --> 06:25:20,718 kind of getting started the answer is 9121 06:25:20,718 --> 06:25:22,798 that one of the philosophies behind the 9122 06:25:22,798 --> 06:25:24,520 go programming language is just to kind 9123 06:25:24,520 --> 06:25:27,558 of keep it simple go doesn't have all 9124 06:25:27,558 --> 06:25:30,400 that many features because go developers 9125 06:25:30,400 --> 06:25:32,478 and go maintainers don't buy into the 9126 06:25:32,478 --> 06:25:34,718 idea that more features necessarily 9127 06:25:34,718 --> 06:25:36,840 makes a better programming language by 9128 06:25:36,840 --> 06:25:38,920 having fewer features it means there's 9129 06:25:38,920 --> 06:25:41,040 less to learn to get up and running with 9130 06:25:41,040 --> 06:25:42,718 the language it also means that anytime 9131 06:25:42,718 --> 06:25:44,478 you see a piece of go code you'll have 9132 06:25:44,478 --> 06:25:46,320 an easier time understanding it and 9133 06:25:46,320 --> 06:25:48,840 working with it so even more so than 9134 06:25:48,840 --> 06:25:50,798 other languages the go team is very 9135 06:25:50,798 --> 06:25:53,360 hesitant to add new stuff so generics 9136 06:25:53,360 --> 06:25:55,558 were in the works for a long time and it 9137 06:25:55,558 --> 06:25:58,000 was only after many years of thinking 9138 06:25:58,000 --> 06:25:59,400 about it and making sure that we really 9139 06:25:59,400 --> 06:26:01,200 needed them uh that they actually got 9140 06:26:01,200 --> 06:26:03,520 their way into the language so the 9141 06:26:03,520 --> 06:26:05,120 question here is is what code would 9142 06:26:05,120 --> 06:26:07,558 generics be most likely to help with a 9143 06:26:07,558 --> 06:26:09,920 binary tree detecting whether or not a 9144 06:26:09,920 --> 06:26:11,958 string contains a given substring or 9145 06:26:11,958 --> 06:26:16,120 calculating the area of a circle well 9146 06:26:16,120 --> 06:26:17,200 detecting whether or not a string 9147 06:26:17,200 --> 06:26:18,600 contains a substring we'll probably just 9148 06:26:18,600 --> 06:26:20,400 use string types and calculating the 9149 06:26:20,400 --> 06:26:22,040 area of a circle just sounds like floats 9150 06:26:22,040 --> 06:26:25,240 to me um but a binary tree is a data 9151 06:26:25,240 --> 06:26:26,958 structure that can store any type it's 9152 06:26:26,958 --> 06:26:28,878 kind of like you know a slice in that 9153 06:26:28,878 --> 06:26:30,478 way um so I'm going to go with binary 9154 06:26:30,478 --> 06:26:32,680 tree on that one the next question is 9155 06:26:32,680 --> 06:26:35,478 Go's approach to language design is to 9156 06:26:35,478 --> 06:26:37,040 support as many useful features as 9157 06:26:37,040 --> 06:26:39,200 possible to resist adding new features 9158 06:26:39,200 --> 06:26:40,878 until they're extremely important or 9159 06:26:40,878 --> 06:26:43,240 proven extremely important or to never 9160 06:26:43,240 --> 06:26:44,760 add new features the language doesn't 9161 06:26:44,760 --> 06:26:47,080 change um and the answer is to just 9162 06:26:47,080 --> 06:26:48,638 resist adding new features unless 9163 06:26:48,638 --> 06:26:51,040 they're proven to be very very important 9164 06:26:51,040 --> 06:26:52,680 the next question is generics will 9165 06:26:52,680 --> 06:26:55,400 probably be used more heavily in blank 9166 06:26:55,400 --> 06:26:57,320 main packages which are executable 9167 06:26:57,320 --> 06:27:00,080 applications or Library packages and I 9168 06:27:00,080 --> 06:27:01,320 definitely argue that they'll be more 9169 06:27:01,320 --> 06:27:04,000 heavily used in library packages okay so 9170 06:27:04,000 --> 06:27:05,558 we we talked about how generics are 9171 06:27:05,558 --> 06:27:08,080 super useful when the type that is being 9172 06:27:08,080 --> 06:27:10,080 used in your function doesn't matter 9173 06:27:10,080 --> 06:27:13,798 right when it can be anything but 9174 06:27:13,798 --> 06:27:16,760 constraints allow us to write generics 9175 06:27:16,760 --> 06:27:18,520 that are actually just useful for a 9176 06:27:18,520 --> 06:27:21,520 subset of types right so maybe this 9177 06:27:21,520 --> 06:27:23,840 function doesn't care too much about the 9178 06:27:23,840 --> 06:27:25,798 types that are being used but it does 9179 06:27:25,798 --> 06:27:28,240 care a little bit so let's take a look 9180 06:27:28,240 --> 06:27:32,040 at an example this concat function is 9181 06:27:32,040 --> 06:27:33,638 similar to the other generics that we've 9182 06:27:33,638 --> 06:27:34,680 worked with 9183 06:27:34,680 --> 06:27:36,520 the big difference is that the type T 9184 06:27:36,520 --> 06:27:38,478 the type parameter instead of being able 9185 06:27:38,478 --> 06:27:41,160 to be anything we're saying it has to be 9186 06:27:41,160 --> 06:27:43,200 a Stringer right and we've specified the 9187 06:27:43,200 --> 06:27:44,798 Stringer interface here it's just 9188 06:27:44,798 --> 06:27:47,080 anything with a string method on it that 9189 06:27:47,080 --> 06:27:50,200 returns a string with the builtin any 9190 06:27:50,200 --> 06:27:51,840 constraint which is effectively the 9191 06:27:51,840 --> 06:27:54,558 empty interface we can't really do 9192 06:27:54,558 --> 06:27:56,400 anything with the values inside the 9193 06:27:56,400 --> 06:27:57,680 functions right which is why it works 9194 06:27:57,680 --> 06:27:58,920 for something where we're just say 9195 06:27:58,920 --> 06:28:02,160 splitting a slice of that type but in 9196 06:28:02,160 --> 06:28:04,120 this function the concat function where 9197 06:28:04,120 --> 06:28:06,680 we're actually able to use the type a 9198 06:28:06,680 --> 06:28:10,600 little bit we're able to call the method 9199 06:28:10,600 --> 06:28:12,958 that's implemented on it and that's just 9200 06:28:12,958 --> 06:28:14,798 because the only thing that we know 9201 06:28:14,798 --> 06:28:16,240 about these values coming into the 9202 06:28:16,240 --> 06:28:18,280 function is that they have that string 9203 06:28:18,280 --> 06:28:20,760 method so what does the concat function 9204 06:28:20,760 --> 06:28:23,958 do well it takes a slice of 9205 06:28:23,958 --> 06:28:27,520 stringers it Loops over all of them 9206 06:28:27,520 --> 06:28:29,920 grabs the string representation right by 9207 06:28:29,920 --> 06:28:31,878 calling that string method the string 9208 06:28:31,878 --> 06:28:33,600 representation of each value and then 9209 06:28:33,600 --> 06:28:35,478 kind of just mashes them all together 9210 06:28:35,478 --> 06:28:37,878 right it concatenates them and Returns 9211 06:28:37,878 --> 06:28:40,360 the result so let's take a look at the 9212 06:28:40,360 --> 06:28:42,320 assignment we have different kinds of 9213 06:28:42,320 --> 06:28:43,920 line items that we can charge our 9214 06:28:43,920 --> 06:28:45,718 customers credit cards for line items 9215 06:28:45,718 --> 06:28:47,558 can be things like subscriptions one or 9216 06:28:47,558 --> 06:28:50,200 onetime payments great complete the 9217 06:28:50,200 --> 06:28:52,680 charge for line item function first it 9218 06:28:52,680 --> 06:28:54,280 should check if the user has a balance 9219 06:28:54,280 --> 06:28:55,798 with enough funds to be able to pay for 9220 06:28:55,798 --> 06:28:58,798 the cost of a new item okay so we're 9221 06:28:58,798 --> 06:29:01,200 given a new item which is of type T 9222 06:29:01,200 --> 06:29:04,120 given a slice of old items and a balance 9223 06:29:04,120 --> 06:29:07,160 is just a float um if they don't have 9224 06:29:07,160 --> 06:29:08,920 enough funds then we'll return an 9225 06:29:08,920 --> 06:29:11,478 insufficient funds error but if they do 9226 06:29:11,478 --> 06:29:13,280 have enough funds then we'll add the 9227 06:29:13,280 --> 06:29:14,878 line item to the user's history by 9228 06:29:14,878 --> 06:29:16,520 appending new item to the slice of old 9229 06:29:16,520 --> 06:29:19,240 old items okay this new slice is your 9230 06:29:19,240 --> 06:29:20,840 first return value right so we're 9231 06:29:20,840 --> 06:29:22,760 returning three values here so we're 9232 06:29:22,760 --> 06:29:25,320 returning kind of the new list of old 9233 06:29:25,320 --> 06:29:28,040 items after new item has been 9234 06:29:28,040 --> 06:29:30,718 appended um and we need to calculate the 9235 06:29:30,718 --> 06:29:32,718 user's New Balance by subtracting the 9236 06:29:32,718 --> 06:29:34,160 cost of the new item from their their 9237 06:29:34,160 --> 06:29:35,840 balance this is my second return value 9238 06:29:35,840 --> 06:29:37,840 Okay cool so we Tak in their balance 9239 06:29:37,840 --> 06:29:39,718 we're going to subtract the cost of the 9240 06:29:39,718 --> 06:29:42,760 new item and then return the New Balance 9241 06:29:42,760 --> 06:29:44,440 um and obviously if nothing went wrong 9242 06:29:44,440 --> 06:29:48,200 we'll return a nil error okay so we have 9243 06:29:48,200 --> 06:29:52,360 the type here as a line item so line 9244 06:29:52,360 --> 06:29:54,040 item is this interface and it looks like 9245 06:29:54,040 --> 06:29:55,718 we we kind of have these two methods 9246 06:29:55,718 --> 06:29:57,638 available to us um within our function 9247 06:29:57,638 --> 06:29:59,680 we can get the cost of a line item or we 9248 06:29:59,680 --> 06:30:02,600 can get the name of a line item so the 9249 06:30:02,600 --> 06:30:03,760 first thing our function is supposed to 9250 06:30:03,760 --> 06:30:05,760 do is check if the user has a balance 9251 06:30:05,760 --> 06:30:07,760 with enough funds so we need to do 9252 06:30:07,760 --> 06:30:12,440 something like uh new new 9253 06:30:12,440 --> 06:30:15,440 balance is equal 9254 06:30:15,440 --> 06:30:17,520 to 9255 06:30:17,520 --> 06:30:19,160 balance 9256 06:30:19,160 --> 06:30:21,718 minus the new 9257 06:30:21,718 --> 06:30:25,400 item. get cost right so we're going to 9258 06:30:25,400 --> 06:30:27,240 check what the New Balance would be 9259 06:30:27,240 --> 06:30:29,280 after subtracting the cost of the item 9260 06:30:29,280 --> 06:30:31,760 from the user's balance then we can say 9261 06:30:31,760 --> 06:30:35,080 if the new balance 9262 06:30:35,080 --> 06:30:37,478 it's less than 9263 06:30:37,478 --> 06:30:40,878 zero then we'll return this insufficient 9264 06:30:40,878 --> 06:30:43,478 funds error right and zero values for 9265 06:30:43,478 --> 06:30:46,958 everything else so it'll be uh nil slice 9266 06:30:46,958 --> 06:30:49,200 0.0 float 9267 06:30:49,200 --> 06:30:53,280 and errors. new insufficient 9268 06:30:53,280 --> 06:30:55,920 funds we'll need the errors 9269 06:30:55,920 --> 06:30:58,680 package okay cool otherwise that means 9270 06:30:58,680 --> 06:31:02,120 this uh this balance is uh zero or 9271 06:31:02,120 --> 06:31:04,478 greater right 9272 06:31:04,478 --> 06:31:07,200 um and it says add the line item to the 9273 06:31:07,200 --> 06:31:08,600 user's history by appending it to the 9274 06:31:08,600 --> 06:31:11,558 slice of old items so we could do old 9275 06:31:11,558 --> 06:31:17,398 items equals append old items new 9276 06:31:17,398 --> 06:31:20,958 item okay this new slice is your first 9277 06:31:20,958 --> 06:31:23,000 return value 9278 06:31:23,000 --> 06:31:25,638 great otherwi um and then calculate the 9279 06:31:25,638 --> 06:31:27,040 the user's New Balance by subtracting 9280 06:31:27,040 --> 06:31:28,240 the cost of the new item from their 9281 06:31:28,240 --> 06:31:30,878 balance so we already did that um this 9282 06:31:30,878 --> 06:31:32,000 is your second return value so I think 9283 06:31:32,000 --> 06:31:34,840 we could just return 9284 06:31:34,840 --> 06:31:39,200 um old items New 9285 06:31:39,200 --> 06:31:42,160 Balance and 9286 06:31:42,160 --> 06:31:47,320 nil right let's go ahead and run 9287 06:31:47,920 --> 06:31:50,520 that okay charging customer for a yearly 9288 06:31:50,520 --> 06:31:52,840 subscription current balance is 1,000 9289 06:31:52,840 --> 06:31:55,600 new balance is 750 total number of line 9290 06:31:55,600 --> 06:31:56,878 items is now 9291 06:31:56,878 --> 06:31:59,080 one for monthly 9292 06:31:59,080 --> 06:32:02,040 subscription new balance is less total 9293 06:32:02,040 --> 06:32:04,360 number of line items is now three let's 9294 06:32:04,360 --> 06:32:06,718 go take a look at those test cases just 9295 06:32:06,718 --> 06:32:10,398 to make sure that this makes 9296 06:32:10,478 --> 06:32:13,040 sense okay so they had zero now they 9297 06:32:13,040 --> 06:32:14,440 have one 9298 06:32:14,440 --> 06:32:16,558 subscription here they had two 9299 06:32:16,558 --> 06:32:19,120 subscriptions now they have three 9300 06:32:19,120 --> 06:32:21,280 subscriptions cool that looks or or 9301 06:32:21,280 --> 06:32:22,638 three L items that looks good to me I'm 9302 06:32:22,638 --> 06:32:24,160 going to go ahead and submit it when 9303 06:32:24,160 --> 06:32:26,398 generics were released a new syntax for 9304 06:32:26,398 --> 06:32:29,558 writing interfaces was also released um 9305 06:32:29,558 --> 06:32:31,478 partly just because this new syntax is 9306 06:32:31,478 --> 06:32:33,478 super useful if you're trying to use 9307 06:32:33,478 --> 06:32:35,680 interface faes as constraints for your 9308 06:32:35,680 --> 06:32:37,798 generic functions so let's take a look 9309 06:32:37,798 --> 06:32:40,240 at an example um a typ list is pretty 9310 06:32:40,240 --> 06:32:41,558 much as simple as it sounds we're 9311 06:32:41,558 --> 06:32:43,040 basically just creating a new interface 9312 06:32:43,040 --> 06:32:44,920 in this case we're calling it ordered 9313 06:32:44,920 --> 06:32:46,600 and then we're just listing all of the 9314 06:32:46,600 --> 06:32:49,520 types that we're saying Implement that 9315 06:32:49,520 --> 06:32:52,958 interface so there's no methods here but 9316 06:32:52,958 --> 06:32:54,558 the interesting thing about all of these 9317 06:32:54,558 --> 06:32:56,958 types is that they all support these 9318 06:32:56,958 --> 06:32:59,200 inequality operators like less than less 9319 06:32:59,200 --> 06:33:01,558 than or equal to greater than and so if 9320 06:33:01,558 --> 06:33:04,840 we use ordered as a cons straint then 9321 06:33:04,840 --> 06:33:07,520 we're free to use these comparison 9322 06:33:07,520 --> 06:33:11,240 operators on that type and the question 9323 06:33:11,240 --> 06:33:12,600 that goes along with this is why might 9324 06:33:12,600 --> 06:33:14,280 you create an interface using a type 9325 06:33:14,280 --> 06:33:16,440 list and the answers are you know 9326 06:33:16,440 --> 06:33:18,000 exactly which type satisfy your 9327 06:33:18,000 --> 06:33:19,878 interface or it's too much trouble to 9328 06:33:19,878 --> 06:33:21,080 define the methods required by your 9329 06:33:21,080 --> 06:33:23,120 interface um that second one is a bad 9330 06:33:23,120 --> 06:33:25,360 reason uh it's you would really only do 9331 06:33:25,360 --> 06:33:27,240 this if you know exactly which types 9332 06:33:27,240 --> 06:33:29,280 satisfy your interface let's take a look 9333 06:33:29,280 --> 06:33:31,760 at parametric constraints which sounds 9334 06:33:31,760 --> 06:33:34,040 like a kind of complex term but it's 9335 06:33:34,040 --> 06:33:35,680 actually really simple it basically just 9336 06:33:35,680 --> 06:33:39,240 means that we can use type parameters in 9337 06:33:39,240 --> 06:33:42,040 interface definitions as well so instead 9338 06:33:42,040 --> 06:33:43,840 of just creating interfaces which we 9339 06:33:43,840 --> 06:33:46,360 then use in our type parameters for 9340 06:33:46,360 --> 06:33:49,000 functions we're actually using type 9341 06:33:49,000 --> 06:33:52,558 parameters to Define new interfaces so 9342 06:33:52,558 --> 06:33:55,680 for example here we have a 9343 06:33:55,680 --> 06:33:59,600 store that takes as a type parameter P 9344 06:33:59,600 --> 06:34:02,200 which is a product now a product is just 9345 06:34:02,200 --> 06:34:04,638 an interface right um it's a product is 9346 06:34:04,638 --> 06:34:07,160 anything that can return a price and a 9347 06:34:07,160 --> 06:34:10,120 name so a store which is again an 9348 06:34:10,120 --> 06:34:13,320 interface is just anything that can sell 9349 06:34:13,320 --> 06:34:16,120 a product now the idea really is that 9350 06:34:16,120 --> 06:34:18,080 simple if you want to get an idea for 9351 06:34:18,080 --> 06:34:20,558 kind of how this whole uh snippet of 9352 06:34:20,558 --> 06:34:22,680 code works the example code I'm not 9353 06:34:22,680 --> 06:34:24,000 going to talk through every line that 9354 06:34:24,000 --> 06:34:25,360 would take a little bit too long but 9355 06:34:25,360 --> 06:34:26,878 feel free to kind of browse through this 9356 06:34:26,878 --> 06:34:29,718 and get a feel for how um that interface 9357 06:34:29,718 --> 06:34:31,680 Works we're going to jump straight into 9358 06:34:31,680 --> 06:34:33,398 the assignment so getting on to the 9359 06:34:33,398 --> 06:34:35,280 assign assment says the Chief Architect 9360 06:34:35,280 --> 06:34:36,920 at maleo has decided she wants us to 9361 06:34:36,920 --> 06:34:38,600 implement billing with generics 9362 06:34:38,600 --> 06:34:39,760 specifically she wants us to create a 9363 06:34:39,760 --> 06:34:41,718 new biller interface a biller is an 9364 06:34:41,718 --> 06:34:43,398 interface that can be used to charge a 9365 06:34:43,398 --> 06:34:45,478 customer and it can also report its name 9366 06:34:45,478 --> 06:34:46,440 okay so let's take a look at what a 9367 06:34:46,440 --> 06:34:49,320 customer is so a customer is this 9368 06:34:49,320 --> 06:34:51,398 interface it's just anything that has a 9369 06:34:51,398 --> 06:34:54,920 get billing email method on it so in 9370 06:34:54,920 --> 06:34:58,000 this case a user is a customer and an 9371 06:34:58,000 --> 06:35:01,440 org is a customer 9372 06:35:01,440 --> 06:35:05,360 okay um and it can also report its name 9373 06:35:05,360 --> 06:35:08,320 okay that's simple enough um there are 9374 06:35:08,320 --> 06:35:09,958 two kinds of billers user billers and 9375 06:35:09,958 --> 06:35:11,958 org billers Okay so we've got user 9376 06:35:11,958 --> 06:35:15,760 biller here and org biller 9377 06:35:15,760 --> 06:35:18,000 here create the new biller interface it 9378 06:35:18,000 --> 06:35:19,200 should have two methods okay so let's go 9379 06:35:19,200 --> 06:35:21,558 ahead and do that 9380 06:35:21,558 --> 06:35:23,240 type 9381 06:35:23,240 --> 06:35:24,760 biller 9382 06:35:24,760 --> 06:35:29,360 interface two methods charge and 9383 06:35:29,360 --> 06:35:31,478 name the good news is the architect 9384 06:35:31,478 --> 06:35:33,120 already wrote the user biller and org 9385 06:35:33,120 --> 06:35:35,240 biller type for us that fill this new B 9386 06:35:35,240 --> 06:35:38,200 interface right we took a look at 9387 06:35:38,200 --> 06:35:40,558 that use the definitions of the types 9388 06:35:40,558 --> 06:35:41,760 and their methods to figure out how to 9389 06:35:41,760 --> 06:35:43,600 write the biller interface on line 7 9390 06:35:43,600 --> 06:35:46,638 Okay cool so let's start with name it 9391 06:35:46,638 --> 06:35:49,200 looks simpler so a user biller um has a 9392 06:35:49,200 --> 06:35:50,798 name method it takes no parameters and 9393 06:35:50,798 --> 06:35:52,600 returns a string uh same with the or 9394 06:35:52,600 --> 06:35:54,920 biller so that one's simple it just 9395 06:35:54,920 --> 06:35:56,120 returns a 9396 06:35:56,120 --> 06:35:58,798 string okay the charge method for user 9397 06:35:58,798 --> 06:36:01,478 biller accepts a user returns a 9398 06:36:01,478 --> 06:36:04,040 bill but for the org Biller accepts an 9399 06:36:04,040 --> 06:36:06,520 org and returns a bill okay so it always 9400 06:36:06,520 --> 06:36:09,360 returns a bill that part's easy but what 9401 06:36:09,360 --> 06:36:12,958 it accepts is a little bit 9402 06:36:12,958 --> 06:36:15,920 different right and if we take a look 9403 06:36:15,920 --> 06:36:18,718 at the customer interface where did it 9404 06:36:18,718 --> 06:36:22,680 go customer interface here then we see 9405 06:36:22,680 --> 06:36:26,440 that we have 9406 06:36:26,440 --> 06:36:28,958 um we have this common interface that we 9407 06:36:28,958 --> 06:36:32,798 can use to represent both a user and an 9408 06:36:32,798 --> 06:36:34,520 orc 9409 06:36:34,520 --> 06:36:36,040 okay so that's convenient because we can 9410 06:36:36,040 --> 06:36:38,558 use that interface right as a parametric 9411 06:36:38,558 --> 06:36:44,558 uh constraint so let's create a new uh 9412 06:36:44,558 --> 06:36:48,680 parametric type or you know but a we'll 9413 06:36:48,680 --> 06:36:51,240 create a new type 9414 06:36:51,240 --> 06:36:54,040 parameter call it C because it's a 9415 06:36:54,040 --> 06:36:56,878 customer should be easy enough and then 9416 06:36:56,878 --> 06:37:01,200 charge will actually take as input 9417 06:37:01,200 --> 06:37:04,120 C right it will take a customer 9418 06:37:04,120 --> 06:37:07,360 rather than specifically a user or an 9419 06:37:07,360 --> 06:37:11,040 org okay let's try 9420 06:37:11,398 --> 06:37:13,878 that it compiled at least let's see what 9421 06:37:13,878 --> 06:37:16,280 we got using basic user biller to create 9422 06:37:16,280 --> 06:37:18,600 a bill for Joe example.com 9423 06:37:18,600 --> 06:37:22,958 $50 basic user biller for Samuel bogs 9424 06:37:22,958 --> 06:37:27,160 $50 Pro user biller for Jade 9425 06:37:27,160 --> 06:37:29,440 $100 okay that's looking correct to me 9426 06:37:29,440 --> 06:37:32,878 it looks like the pro uh Pro and basic 9427 06:37:32,878 --> 06:37:35,120 uh have a discrepancy of $50 and $100 9428 06:37:35,120 --> 06:37:37,398 and then the org biller is being used 9429 06:37:37,398 --> 06:37:39,638 here you can see it's actually much more 9430 06:37:39,638 --> 06:37:42,160 expensive so that looks correct to me so 9431 06:37:42,160 --> 06:37:44,680 let's talk about naming generic types uh 9432 06:37:44,680 --> 06:37:46,440 we can take a look at this old example 9433 06:37:46,440 --> 06:37:47,878 or the example from earlier in the 9434 06:37:47,878 --> 06:37:50,200 course where we had to split any slice 9435 06:37:50,200 --> 06:37:52,760 right and it has t as a type parameter 9436 06:37:52,760 --> 06:37:55,718 um of type any and then we use T um kind 9437 06:37:55,718 --> 06:37:57,718 of all throughout the function signature 9438 06:37:57,718 --> 06:37:59,958 um T is just a variable name it doesn't 9439 06:37:59,958 --> 06:38:01,718 we don't have to use T there we could 9440 06:38:01,718 --> 06:38:03,718 name we could name this whatever we want 9441 06:38:03,718 --> 06:38:07,000 right we could name it my type uh 9442 06:38:07,000 --> 06:38:09,520 whatever the heck we want right uh slice 9443 06:38:09,520 --> 06:38:12,680 value it doesn't matter um however it 9444 06:38:12,680 --> 06:38:14,840 turns out that capital t is actually 9445 06:38:14,840 --> 06:38:17,878 fairly common convention um when there 9446 06:38:17,878 --> 06:38:20,440 is just a single type parameter for a 9447 06:38:20,440 --> 06:38:22,520 function so the question here is the 9448 06:38:22,520 --> 06:38:25,958 name of a type parameter blank can and 9449 06:38:25,958 --> 06:38:27,958 should be whatever you want can be 9450 06:38:27,958 --> 06:38:30,520 anything but T is a common convention or 9451 06:38:30,520 --> 06:38:32,958 must be t uh it turns out it can be 9452 06:38:32,958 --> 06:38:34,760 anything but but T is a fairly common 9453 06:38:34,760 --> 06:38:37,398 conventional name Rob Pike one of the 9454 06:38:37,398 --> 06:38:39,280 creators of the go programming language 9455 06:38:39,280 --> 06:38:42,120 created an awesome set of Proverbs that 9456 06:38:42,120 --> 06:38:44,440 outlines some more of the philosophies 9457 06:38:44,440 --> 06:38:46,440 behind the language I'm not going to 9458 06:38:46,440 --> 06:38:48,120 read them all to you but I am going to 9459 06:38:48,120 --> 06:38:50,360 cover some of the ones that I think are 9460 06:38:50,360 --> 06:38:52,398 the most important and if you are 9461 06:38:52,398 --> 06:38:54,360 interested I'd highly recommend going 9462 06:38:54,360 --> 06:38:57,160 and watching his talk about the Proverbs 9463 06:38:57,160 --> 06:38:58,958 uh if if you want to go more in depth on 9464 06:38:58,958 --> 06:39:01,280 them so let's start at the top don't 9465 06:39:01,280 --> 06:39:03,840 communicate by sharing memory share 9466 06:39:03,840 --> 06:39:06,840 memory by communicating so this 9467 06:39:06,840 --> 06:39:08,360 basically is telling us we should 9468 06:39:08,360 --> 06:39:11,878 probably try to use channels more often 9469 06:39:11,878 --> 06:39:13,798 than we use mutexes when we're trying to 9470 06:39:13,798 --> 06:39:17,040 share memory between go routines which 9471 06:39:17,040 --> 06:39:19,760 leads right into the third one which is 9472 06:39:19,760 --> 06:39:23,000 channels orchestrate and mutexes 9473 06:39:23,000 --> 06:39:26,398 serialize so when we use channels we get 9474 06:39:26,398 --> 06:39:28,680 kind of this elegant flow of data 9475 06:39:28,680 --> 06:39:31,240 through our program right one go routine 9476 06:39:31,240 --> 06:39:33,440 did something another go routine can 9477 06:39:33,440 --> 06:39:35,920 react to it mutexes are all about just 9478 06:39:35,920 --> 06:39:38,638 locking access to protected resources if 9479 06:39:38,638 --> 06:39:41,080 we can use channels to express logic in 9480 06:39:41,080 --> 06:39:43,638 our program it will tend to work a 9481 06:39:43,638 --> 06:39:45,680 little bit better another great one is 9482 06:39:45,680 --> 06:39:49,200 that the empty interface says nothing 9483 06:39:49,200 --> 06:39:52,080 right every type in go fulfills the 9484 06:39:52,080 --> 06:39:54,240 empty interface you should really avoid 9485 06:39:54,240 --> 06:39:56,600 using the empty interface just because 9486 06:39:56,600 --> 06:39:58,760 it doesn't tell you anything interesting 9487 06:39:58,760 --> 06:40:01,718 about your types the empty interface is 9488 06:40:01,718 --> 06:40:03,920 sometimes used by new go Developers to 9489 06:40:03,920 --> 06:40:06,320 kind of get around the type system and 9490 06:40:06,320 --> 06:40:09,160 that just leads to unsafe code go format 9491 06:40:09,160 --> 06:40:11,718 style is no one's favorite and yet go 9492 06:40:11,718 --> 06:40:14,000 format style is everyone's favorite so 9493 06:40:14,000 --> 06:40:15,840 we'll get into this in just a bit when 9494 06:40:15,840 --> 06:40:18,080 we jump into the project but the go tool 9495 06:40:18,080 --> 06:40:20,320 chain comes with its own formatter and 9496 06:40:20,320 --> 06:40:22,320 pretty much every production piece of go 9497 06:40:22,320 --> 06:40:25,398 code out there uses the same formatter 9498 06:40:25,398 --> 06:40:27,280 which is fantastic because it means all 9499 06:40:27,280 --> 06:40:30,680 go code looks the same while not 9500 06:40:30,680 --> 06:40:33,360 everyone necessarily agrees on the form 9501 06:40:33,360 --> 06:40:36,360 matters choice of say tabs versus spaces 9502 06:40:36,360 --> 06:40:38,398 it's still everyone's favorite because 9503 06:40:38,398 --> 06:40:40,558 it means we all get something consistent 9504 06:40:40,558 --> 06:40:42,958 that works reasonably well the next one 9505 06:40:42,958 --> 06:40:45,000 is one of my favorites it's a little 9506 06:40:45,000 --> 06:40:46,478 copying is better than a little 9507 06:40:46,478 --> 06:40:48,320 dependency now if you've ever worked in 9508 06:40:48,320 --> 06:40:50,440 the JavaScript ecosystem with node 9509 06:40:50,440 --> 06:40:52,240 modules you'll know exactly what this 9510 06:40:52,240 --> 06:40:54,840 means node modules is typically a huge 9511 06:40:54,840 --> 06:40:56,718 folder and a lot of times when you're 9512 06:40:56,718 --> 06:40:59,040 working on a front-end framework your 9513 06:40:59,040 --> 06:41:01,558 dependencies are much greater than your 9514 06:41:01,558 --> 06:41:04,160 actual application code and in go we 9515 06:41:04,160 --> 06:41:06,160 typically just kind of invert that way 9516 06:41:06,160 --> 06:41:08,718 of thinking we want our application code 9517 06:41:08,718 --> 06:41:11,398 to be the bulk of the code within our 9518 06:41:11,398 --> 06:41:13,680 project and we tend to use far fewer 9519 06:41:13,680 --> 06:41:16,878 dependencies as almost a philosophy and 9520 06:41:16,878 --> 06:41:19,478 this brings us to the one uh mentioned 9521 06:41:19,478 --> 06:41:21,558 here in the question which says which is 9522 06:41:21,558 --> 06:41:23,718 better clear or clever and at least 9523 06:41:23,718 --> 06:41:27,000 according to rag Pike clear is better 9524 06:41:27,000 --> 06:41:29,638 than clever so if you can write your 9525 06:41:29,638 --> 06:41:31,718 code in a way that is very clear to 9526 06:41:31,718 --> 06:41:33,440 anyone else reading it or even just to 9527 06:41:33,440 --> 06:41:35,280 yourself that's better than trying to do 9528 06:41:35,280 --> 06:41:37,478 a trick that might seem clever but is 9529 06:41:37,478 --> 06:41:39,638 actually hard for humans to understand 9530 06:41:39,638 --> 06:41:42,240 remember code is written for humans not 9531 06:41:42,240 --> 06:41:43,958 for 9532 06:41:43,958 --> 06:41:46,000 machines the next question is which is 9533 06:41:46,000 --> 06:41:48,280 better copying a little code or 9534 06:41:48,280 --> 06:41:51,160 including a small dependency and Rob 9535 06:41:51,160 --> 06:41:53,000 Pike would argue that it's typically 9536 06:41:53,000 --> 06:41:55,398 better to copy a little bit of code 9537 06:41:55,398 --> 06:41:57,040 rather than include a very small 9538 06:41:57,040 --> 06:41:59,280 dependency in your project the next one 9539 06:41:59,280 --> 06:42:01,360 I want to point out is that errors are 9540 06:42:01,360 --> 06:42:04,520 just values right and go error is just a 9541 06:42:04,520 --> 06:42:06,440 specific interface and we return it from 9542 06:42:06,440 --> 06:42:08,080 functions just like we do any other 9543 06:42:08,080 --> 06:42:10,440 value there's not some special way to 9544 06:42:10,440 --> 06:42:12,558 handle errors with tries and catches 9545 06:42:12,558 --> 06:42:14,718 errors are just values and we deal with 9546 06:42:14,718 --> 06:42:18,320 them just like we would any other 9547 06:42:20,000 --> 06:42:22,398 value the last one I want to point out 9548 06:42:22,398 --> 06:42:25,440 is that documentation is for users this 9549 06:42:25,440 --> 06:42:27,478 is actually an interesting one I think 9550 06:42:27,478 --> 06:42:30,320 what he's saying here and I I need to go 9551 06:42:30,320 --> 06:42:33,160 rewatch The talk to confirm but that 9552 06:42:33,160 --> 06:42:34,798 documentation is primarily for people 9553 06:42:34,798 --> 06:42:36,958 who aren't maintaining the code in other 9554 06:42:36,958 --> 06:42:39,718 words it's best if the code itself is 9555 06:42:39,718 --> 06:42:41,478 really easy to understand so it doesn't 9556 06:42:41,478 --> 06:42:43,680 need to be heavily documented so that 9557 06:42:43,680 --> 06:42:46,000 other maintainers can work on it right 9558 06:42:46,000 --> 06:42:48,120 um documentation in the sense that you 9559 06:42:48,120 --> 06:42:49,680 know we should be writing external 9560 06:42:49,680 --> 06:42:51,440 documents that explain how the code work 9561 06:42:51,440 --> 06:42:53,280 or or how to use it should be for the 9562 06:42:53,280 --> 06:42:55,878 users of our code right in the sense 9563 06:42:55,878 --> 06:42:57,760 that if we're writing a library we 9564 06:42:57,760 --> 06:42:59,440 should be writing documentation for the 9565 06:42:59,440 --> 06:43:02,478 users of the library um the developers 9566 06:43:02,478 --> 06:43:05,280 calling our exported functions right not 9567 06:43:05,280 --> 06:43:08,718 the maintainers of the library itself so 9568 06:43:08,718 --> 06:43:10,040 documentation should primarily be 9569 06:43:10,040 --> 06:43:12,920 written for the users of your code it's 9570 06:43:12,920 --> 06:43:15,440 time to build a fully fledged backend 9571 06:43:15,440 --> 06:43:18,000 server Ino from scratch on our local 9572 06:43:18,000 --> 06:43:20,280 machines the purpose of the server will 9573 06:43:20,280 --> 06:43:22,958 be to aggregate data from RSS feeds if 9574 06:43:22,958 --> 06:43:24,558 you're not familiar with RSS it's a 9575 06:43:24,558 --> 06:43:26,360 protocol that makes Distributing things 9576 06:43:26,360 --> 06:43:29,000 like podcast and blog posts really easy 9577 06:43:29,000 --> 06:43:30,958 so what our server will allow users to 9578 06:43:30,958 --> 06:43:34,160 do is add different RSS feeds to its 9579 06:43:34,160 --> 06:43:35,878 database and then it will go 9580 06:43:35,878 --> 06:43:38,558 automatically collect all of the posts 9581 06:43:38,558 --> 06:43:40,840 from those feeds and download them and 9582 06:43:40,840 --> 06:43:42,638 save them in the database so that we can 9583 06:43:42,638 --> 06:43:45,080 then view them later before we get 9584 06:43:45,080 --> 06:43:47,320 started there are four things you're 9585 06:43:47,320 --> 06:43:50,798 going to need the first is a basic 9586 06:43:50,798 --> 06:43:53,080 understanding of SQL the language that's 9587 06:43:53,080 --> 06:43:54,958 most often used to query relational 9588 06:43:54,958 --> 06:43:56,718 databases if you're not familiar with 9589 06:43:56,718 --> 06:43:59,320 SQL yet that's okay I've got a full 9590 06:43:59,320 --> 06:44:01,478 course on SQL I'll link that down in the 9591 06:44:01,478 --> 06:44:03,280 description below go watch that then 9592 06:44:03,280 --> 06:44:04,920 come back here if you're not familiar 9593 06:44:04,920 --> 06:44:07,280 with SQL number two is you're going to 9594 06:44:07,280 --> 06:44:09,520 need a text editor and a command line 9595 06:44:09,520 --> 06:44:12,440 I'm using vs code and zsh uh here in the 9596 06:44:12,440 --> 06:44:14,080 video so you'll see me using that uh 9597 06:44:14,080 --> 06:44:16,280 feel free to go download those if uh you 9598 06:44:16,280 --> 06:44:17,840 want to try them out but you can use 9599 06:44:17,840 --> 06:44:19,920 whatever text editor you want as long as 9600 06:44:19,920 --> 06:44:21,958 it can edit your files and you have 9601 06:44:21,958 --> 06:44:24,600 access to a terminal to run commands 9602 06:44:24,600 --> 06:44:26,558 number three is the go programming 9603 06:44:26,558 --> 06:44:28,200 language itself if you don't have that 9604 06:44:28,200 --> 06:44:30,240 you can go download it I will link uh 9605 06:44:30,240 --> 06:44:31,638 the download page down in the 9606 06:44:31,638 --> 06:44:33,040 description below and I'd also recom 9607 06:44:33,040 --> 06:44:36,080 recommend just installing the go plugin 9608 06:44:36,080 --> 06:44:37,520 um if you're in VSS code there is an 9609 06:44:37,520 --> 06:44:39,600 official go plugin Go download that 9610 06:44:39,600 --> 06:44:41,360 it'll make your life easier with syntax 9611 06:44:41,360 --> 06:44:42,920 highlighting and formatting and that 9612 06:44:42,920 --> 06:44:45,240 sort of thing number four the last thing 9613 06:44:45,240 --> 06:44:49,080 you'll need is an HTTP client so an HTTP 9614 06:44:49,080 --> 06:44:50,958 client will allow you to make get and 9615 06:44:50,958 --> 06:44:53,600 post and put requests into the web 9616 06:44:53,600 --> 06:44:55,558 server that we're building we'll need 9617 06:44:55,558 --> 06:44:57,558 that for testing I use the Thunder 9618 06:44:57,558 --> 06:45:00,000 client it's a vs code extension but you 9619 06:45:00,000 --> 06:45:01,718 can use anything you like even curl on 9620 06:45:01,718 --> 06:45:03,840 the command line or post and insomnia 9621 06:45:03,840 --> 06:45:06,120 there's tons of choices Google HTTP 9622 06:45:06,120 --> 06:45:07,958 clients um or if you don't already have 9623 06:45:07,958 --> 06:45:10,320 a preference again if you're in vs code 9624 06:45:10,320 --> 06:45:12,080 I'd recommend the Thunder client 9625 06:45:12,080 --> 06:45:14,398 extension now that you have all of those 9626 06:45:14,398 --> 06:45:16,840 tools installed and hopefully working 9627 06:45:16,840 --> 06:45:18,478 let's jump into the project the first 9628 06:45:18,478 --> 06:45:19,840 thing we're going to need is just a 9629 06:45:19,840 --> 06:45:22,398 main.go file we'll create our entry 9630 06:45:22,398 --> 06:45:24,680 point um it will be a part of the main 9631 06:45:24,680 --> 06:45:28,280 package and it will need a main function 9632 06:45:28,280 --> 06:45:30,798 so Funk main takes no arguments return 9633 06:45:30,798 --> 06:45:33,320 those returns no parameters and for now 9634 06:45:33,320 --> 06:45:35,240 let's just print hello world make sure 9635 06:45:35,240 --> 06:45:37,440 we can kind of build and run this 9636 06:45:37,440 --> 06:45:39,760 program um we're going to need to 9637 06:45:39,760 --> 06:45:42,280 initialize a new module for our project 9638 06:45:42,280 --> 06:45:45,718 so I'm going to do go mod in it and I 9639 06:45:45,718 --> 06:45:47,320 like to name my modules after their 9640 06:45:47,320 --> 06:45:49,920 remote path right where they will exist 9641 06:45:49,920 --> 06:45:52,000 um kind of out on the internet so uh in 9642 06:45:52,000 --> 06:45:55,680 my case I use github.com my GitHub uh 9643 06:45:55,680 --> 06:45:58,398 namespace which is Wags Lane slash the 9644 06:45:58,398 --> 06:46:01,080 name of this repository which again is 9645 06:46:01,080 --> 06:46:02,600 where I'll be keeping this code on 9646 06:46:02,600 --> 06:46:04,878 GitHub so I highly recommend you keep 9647 06:46:04,878 --> 06:46:07,638 track of this code in GitHub this entire 9648 06:46:07,638 --> 06:46:09,958 project should be checked into git and 9649 06:46:09,958 --> 06:46:12,718 uploaded to GitHub or gitlab or whatever 9650 06:46:12,718 --> 06:46:15,520 you prefer um so I'm going to name this 9651 06:46:15,520 --> 06:46:20,320 repository um RSS aggregator RSS a so 9652 06:46:20,320 --> 06:46:22,878 we'll go ahead and create that that will 9653 06:46:22,878 --> 06:46:25,000 create this new go 9654 06:46:25,000 --> 06:46:27,240 module and now that that's ready we 9655 06:46:27,240 --> 06:46:29,320 should be able to just go 9656 06:46:29,320 --> 06:46:33,840 build and execute the new uh binary or 9657 06:46:33,840 --> 06:46:35,520 the new executable that will be created 9658 06:46:35,520 --> 06:46:36,958 from go build in fact I'll just run it 9659 06:46:36,958 --> 06:46:39,798 once so you can see I created this new 9660 06:46:39,798 --> 06:46:43,320 binary file here in my current directory 9661 06:46:43,320 --> 06:46:45,040 and so from now on I'll be running this 9662 06:46:45,040 --> 06:46:48,478 command go build and 9663 06:46:48,478 --> 06:46:52,680 slash RSS a so that will build and run 9664 06:46:52,680 --> 06:46:54,360 and we got hello world back so we're 9665 06:46:54,360 --> 06:46:56,478 good to go like I said before we're 9666 06:46:56,478 --> 06:46:58,360 going to be building this project with 9667 06:46:58,360 --> 06:47:00,120 Git and storing our code in Source 9668 06:47:00,120 --> 06:47:01,920 control as we go so I'm going to go 9669 06:47:01,920 --> 06:47:03,878 ahead and create a new 9670 06:47:03,878 --> 06:47:06,280 get repository and in vs code it 9671 06:47:06,280 --> 06:47:08,478 highlights all the code that has changed 9672 06:47:08,478 --> 06:47:10,200 but not yet been committed to Source 9673 06:47:10,200 --> 06:47:12,120 control here in green um but I don't 9674 06:47:12,120 --> 06:47:13,798 want all of this in my source control 9675 06:47:13,798 --> 06:47:16,000 the vs code file is configurations for 9676 06:47:16,000 --> 06:47:17,798 my editor um that's a personal thing 9677 06:47:17,798 --> 06:47:19,440 that doesn't need to be in the project 9678 06:47:19,440 --> 06:47:22,360 itself um same with the RSS a binary we 9679 06:47:22,360 --> 06:47:24,558 don't want to commit the binary that 9680 06:47:24,558 --> 06:47:26,280 we're building or the executable file 9681 06:47:26,280 --> 06:47:27,798 that we're building we just want to 9682 06:47:27,798 --> 06:47:30,040 commit our source code so I'm going to 9683 06:47:30,040 --> 06:47:33,798 create a newg ignore file 9684 06:47:33,798 --> 06:47:36,280 and we're going to ignore the vs code 9685 06:47:36,280 --> 06:47:40,798 folder and the RSS a 9686 06:47:40,798 --> 06:47:45,680 binary and next um we're going to add 9687 06:47:45,680 --> 06:47:47,600 all of the secrets the like 9688 06:47:47,600 --> 06:47:50,718 configuration Secrets uh for our project 9689 06:47:50,718 --> 06:47:54,600 in a EnV file and read them out of the 9690 06:47:54,600 --> 06:47:57,320 file itself so uh for example one of the 9691 06:47:57,320 --> 06:47:58,798 configuration variables that we're going 9692 06:47:58,798 --> 06:48:00,638 to set is the port that the server will 9693 06:48:00,638 --> 06:48:03,360 run on so um I'm going to set that port 9694 06:48:03,360 --> 06:48:05,360 to 9695 06:48:05,360 --> 06:48:09,320 8,000 and I'm going to also ignore thatv 9696 06:48:09,320 --> 06:48:10,920 file in the G 9697 06:48:10,920 --> 06:48:13,440 ignore again because configuration data 9698 06:48:13,440 --> 06:48:15,638 is something kind of local to my machine 9699 06:48:15,638 --> 06:48:17,798 in production this port might be 9700 06:48:17,798 --> 06:48:19,240 something different so we don't need to 9701 06:48:19,240 --> 06:48:21,558 commit this file to Source control um 9702 06:48:21,558 --> 06:48:24,920 but I do want it here in my repo now at 9703 06:48:24,920 --> 06:48:27,478 this point I do want to pause and say if 9704 06:48:27,478 --> 06:48:30,440 you have no idea what a port is or you 9705 06:48:30,440 --> 06:48:33,040 have no idea what HTTP requests are or 9706 06:48:33,040 --> 06:48:35,798 rest apis are um we're going to move 9707 06:48:35,798 --> 06:48:38,160 fairly quickly in this project so if 9708 06:48:38,160 --> 06:48:39,558 you're not familiar with that stuff 9709 06:48:39,558 --> 06:48:40,920 again I will link down in the 9710 06:48:40,920 --> 06:48:43,520 description below my HTTP course that 9711 06:48:43,520 --> 06:48:45,478 would be a good one to go brush up on 9712 06:48:45,478 --> 06:48:48,478 before working on this project so now we 9713 06:48:48,478 --> 06:48:51,638 need a way to read this port variable 9714 06:48:51,638 --> 06:48:54,200 into our program so that we can use it 9715 06:48:54,200 --> 06:48:56,000 and the ghost standard library has a 9716 06:48:56,000 --> 06:48:59,478 built-in uh function called os. getet n 9717 06:48:59,478 --> 06:49:01,600 so it's a an exported function called 9718 06:49:01,600 --> 06:49:05,080 get end from the OS package and we can 9719 06:49:05,080 --> 06:49:07,478 get the value of a variable by its key 9720 06:49:07,478 --> 06:49:09,520 so in this case the key is 9721 06:49:09,520 --> 06:49:14,798 port and we'll get back a port 9722 06:49:14,798 --> 06:49:17,718 string and then for now let's just uh 9723 06:49:17,718 --> 06:49:21,040 let's just say if Port string equals the 9724 06:49:21,040 --> 06:49:23,478 empty string then we'll 9725 06:49:23,478 --> 06:49:28,360 say uh log. fatal so log. fatal will 9726 06:49:28,360 --> 06:49:30,080 exit the program immediately with arrow 9727 06:49:30,080 --> 06:49:34,398 code one and a message and we'll say uh 9728 06:49:34,398 --> 06:49:39,080 Port is not found in the 9729 06:49:39,080 --> 06:49:42,478 environment otherwise we'll 9730 06:49:42,478 --> 06:49:44,920 say 9731 06:49:44,920 --> 06:49:48,360 port and we'll print the port string 9732 06:49:48,360 --> 06:49:51,520 okay cool let's go ahead and run 9733 06:49:56,280 --> 06:49:58,360 that Port is not found in the 9734 06:49:58,360 --> 06:50:00,878 environment okay so the problem here is 9735 06:50:00,878 --> 06:50:03,280 that Port the environment variable 9736 06:50:03,280 --> 06:50:05,440 doesn't exist in my current shell 9737 06:50:05,440 --> 06:50:07,638 session if I wanted to add it I could 9738 06:50:07,638 --> 06:50:11,520 run in my in my command line export Port 9739 06:50:11,520 --> 06:50:13,120 equals 9740 06:50:13,120 --> 06:50:16,798 8000 and then run this again and then we 9741 06:50:16,798 --> 06:50:18,958 get Port equals 8,000 the problem is I 9742 06:50:18,958 --> 06:50:22,000 don't want to manually set this 9743 06:50:22,000 --> 06:50:23,718 environment variable every time I work 9744 06:50:23,718 --> 06:50:26,440 on my server I want to pull it from this 9745 06:50:26,440 --> 06:50:29,440 file so we're going to use a package 9746 06:50:29,440 --> 06:50:30,958 that allows us to grab environment 9747 06:50:30,958 --> 06:50:33,240 variables from a file 9748 06:50:33,240 --> 06:50:36,040 um and it is this package here 9749 06:50:36,040 --> 06:50:37,478 github.com 9750 06:50:37,478 --> 06:50:41,558 jooho go. EnV um that's also the URL of 9751 06:50:41,558 --> 06:50:43,558 the library you can paste that into your 9752 06:50:43,558 --> 06:50:45,680 browser uh go check it out but we're 9753 06:50:45,680 --> 06:50:48,320 just going to install it here 9754 06:50:48,320 --> 06:50:51,798 locally and that will add it here to our 9755 06:50:51,798 --> 06:50:55,280 go.mod and then I'm going to run go 9756 06:50:55,280 --> 06:51:01,200 vendor to copy that code here into uh my 9757 06:51:01,200 --> 06:51:04,240 my vendor folder um we get kind of a 9758 06:51:04,240 --> 06:51:09,520 local copy of that and we'll run um here 9759 06:51:09,520 --> 06:51:10,920 we're going to need to actually use it 9760 06:51:10,920 --> 06:51:17,160 so we do go. env. load and by default 9761 06:51:17,160 --> 06:51:21,040 load loads the uhv file I think we can 9762 06:51:21,040 --> 06:51:26,080 also optionally pass in EnV as the file 9763 06:51:26,080 --> 06:51:28,638 path and what's uh what's my error here 9764 06:51:28,638 --> 06:51:31,280 could not import no required module 9765 06:51:31,280 --> 06:51:33,160 provides 9766 06:51:33,160 --> 06:51:35,360 go let's go mod 9767 06:51:35,360 --> 06:51:37,760 tidy that should clean up my imports 9768 06:51:37,760 --> 06:51:39,958 okay 9769 06:51:40,680 --> 06:51:42,760 perfect 9770 06:51:42,760 --> 06:51:45,040 and do I need to do anything else what 9771 06:51:45,040 --> 06:51:47,080 are we getting here could not import no 9772 06:51:47,080 --> 06:51:48,440 required module oh I should probably go 9773 06:51:48,440 --> 06:51:51,000 mod vendor 9774 06:51:51,478 --> 06:51:53,878 again that should pull in the code okay 9775 06:51:53,878 --> 06:51:56,040 so you can see we've kind of imported 9776 06:51:56,040 --> 06:51:58,718 and downloaded all of that code from the 9777 06:51:58,718 --> 06:52:00,840 package and now I'm not getting error 9778 06:52:00,840 --> 06:52:03,280 any errors in my console okay so this 9779 06:52:03,280 --> 06:52:04,920 will take the environment variables from 9780 06:52:04,920 --> 06:52:07,958 myv file and pull them into my current 9781 06:52:07,958 --> 06:52:10,558 environment so that then I can use os. 9782 06:52:10,558 --> 06:52:13,160 get EnV to load the variable so to test 9783 06:52:13,160 --> 06:52:15,520 that let's go ahead and change uh the 9784 06:52:15,520 --> 06:52:17,080 port to 9785 06:52:17,080 --> 06:52:20,798 8080 and rerun the 9786 06:52:21,478 --> 06:52:23,958 server still says 8,000 so something 9787 06:52:23,958 --> 06:52:25,600 went wrong maybe I'm misremembering how 9788 06:52:25,600 --> 06:52:28,160 to use this uh use this 9789 06:52:28,160 --> 06:52:32,600 package let's try just go. .load 9790 06:52:32,600 --> 06:52:34,200 still Port 9791 06:52:34,200 --> 06:52:37,798 80 what am I doing wrong does it not 9792 06:52:37,798 --> 06:52:39,638 overwrite you know what it might not 9793 06:52:39,638 --> 06:52:41,160 overwrite my current session I'm going 9794 06:52:41,160 --> 06:52:43,320 to kill my current cell session shell 9795 06:52:43,320 --> 06:52:46,398 session and create a new one then we'll 9796 06:52:46,398 --> 06:52:49,000 do this again so now I won't have that 9797 06:52:49,000 --> 06:52:52,840 exported 8,000 that I had in my terminal 9798 06:52:52,840 --> 06:52:56,478 um run that again okay cool so now it's 9799 06:52:56,478 --> 06:52:58,360 pulling it from the file because I don't 9800 06:52:58,360 --> 06:53:00,558 already have it defined in my shell 9801 06:53:00,558 --> 06:53:02,760 session now I want to take just a second 9802 06:53:02,760 --> 06:53:04,520 and point out there are text 9803 06:53:04,520 --> 06:53:06,600 instructions for this entire project 9804 06:53:06,600 --> 06:53:09,080 over on boot. and I'll link that down in 9805 06:53:09,080 --> 06:53:10,398 the description below we're going to be 9806 06:53:10,398 --> 06:53:12,798 using a lot of text uh you know code 9807 06:53:12,798 --> 06:53:15,120 Snippets from those text instructions 9808 06:53:15,120 --> 06:53:16,878 and they'll be easier to kind of copy 9809 06:53:16,878 --> 06:53:19,958 and paste and grab from boot. directly 9810 06:53:19,958 --> 06:53:21,360 than trying to you know retype what 9811 06:53:21,360 --> 06:53:23,680 you're seeing me type here on the screen 9812 06:53:23,680 --> 06:53:25,440 now we're going to actually spin up our 9813 06:53:25,440 --> 06:53:27,000 server and we're going to be using the 9814 06:53:27,000 --> 06:53:29,440 chi router to do it it's a third-party 9815 06:53:29,440 --> 06:53:31,878 router uh very lightweight built on top 9816 06:53:31,878 --> 06:53:33,398 of kind of the the same way that the 9817 06:53:33,398 --> 06:53:36,760 standard library in go does http routers 9818 06:53:36,760 --> 06:53:37,958 and so let's go ahead and install those 9819 06:53:37,958 --> 06:53:41,798 now we'll do go get um github.com 9820 06:53:41,798 --> 06:53:45,680 gochi chai or chi I always struggle to 9821 06:53:45,680 --> 06:53:48,160 pronounce that one um we'll install that 9822 06:53:48,160 --> 06:53:51,080 and we'll install the the cores package 9823 06:53:51,080 --> 06:53:54,120 from the same uh the same Nam space the 9824 06:53:54,120 --> 06:53:56,920 chi namespace next we'll create a new 9825 06:53:56,920 --> 06:53:59,840 router so I'll do router colon equals 9826 06:53:59,840 --> 06:54:02,760 chi. new router 9827 06:54:02,760 --> 06:54:06,920 fact I should probably go mod 9828 06:54:07,680 --> 06:54:09,760 vendor have it there and then I'll do 9829 06:54:09,760 --> 06:54:13,000 another go mod tidy and go mod vender to 9830 06:54:13,000 --> 06:54:14,320 bring it 9831 06:54:14,320 --> 06:54:17,558 in cool so this creates a new router 9832 06:54:17,558 --> 06:54:20,440 object next we'll connect up this router 9833 06:54:20,440 --> 06:54:23,878 to an HTTP do server so serve colon 9834 06:54:23,878 --> 06:54:27,558 equals a pointer to an HTTP do 9835 06:54:27,558 --> 06:54:31,760 server and a server needs a Handler 9836 06:54:31,760 --> 06:54:33,760 which will be router 9837 06:54:33,760 --> 06:54:38,958 itself and we also need a or an address 9838 06:54:38,958 --> 06:54:43,478 which is just a colon plus that Port 9839 06:54:43,478 --> 06:54:46,398 string so in this case it'll be colon 9840 06:54:46,398 --> 06:54:49,200 you know 8080 cool and then we can call 9841 06:54:49,200 --> 06:54:52,638 HTTP do listen and 9842 06:54:52,638 --> 06:54:55,160 serve or sorry not HTTP listen and serve 9843 06:54:55,160 --> 06:54:56,760 we want to call it on the server object 9844 06:54:56,760 --> 06:55:00,440 so serve. listen and serve cool and 9845 06:55:00,440 --> 06:55:02,398 before we call that in fact I think that 9846 06:55:02,398 --> 06:55:04,440 returns an error so let's capture that 9847 06:55:04,440 --> 06:55:07,680 error and say if error does not equal 9848 06:55:07,680 --> 06:55:10,080 nil log. 9849 06:55:10,080 --> 06:55:13,360 fatal pass in the air as a 9850 06:55:13,360 --> 06:55:17,040 message okay listen and serve will block 9851 06:55:17,040 --> 06:55:20,160 so when we get to line 30 our our code 9852 06:55:20,160 --> 06:55:21,718 basically just stops right here and 9853 06:55:21,718 --> 06:55:25,160 starts handling HTTP requests if 9854 06:55:25,160 --> 06:55:27,160 anything goes wrong in the process of 9855 06:55:27,160 --> 06:55:29,440 handling those requests then an error 9856 06:55:29,440 --> 06:55:32,080 will be returned and we'll you know log 9857 06:55:32,080 --> 06:55:34,478 in and exit the program but kind of the 9858 06:55:34,478 --> 06:55:37,160 happy path for our code is that you know 9859 06:55:37,160 --> 06:55:38,878 nothing should ever be returned from 9860 06:55:38,878 --> 06:55:40,520 listen and serve because our server is 9861 06:55:40,520 --> 06:55:42,878 just going to run forever before we run 9862 06:55:42,878 --> 06:55:45,200 this let's just add one more kind of 9863 06:55:45,200 --> 06:55:47,840 logging statement we'll do log. print 9864 06:55:47,840 --> 06:55:51,160 line actually let's do print F and we'll 9865 06:55:51,160 --> 06:55:56,120 say server starting on 9866 06:55:56,120 --> 06:56:00,440 portent V and we'll pass in that Port 9867 06:56:00,440 --> 06:56:03,360 string okay cool with that let's go 9868 06:56:03,360 --> 06:56:07,040 ahead and build and run again so go 9869 06:56:08,040 --> 06:56:10,878 build see what we 9870 06:56:10,878 --> 06:56:13,520 get Hello World server starting on Port 9871 06:56:13,520 --> 06:56:15,680 880 I should probably remove should 9872 06:56:15,680 --> 06:56:17,080 probably remove that hello world at this 9873 06:56:17,080 --> 06:56:19,440 point now that we have a running server 9874 06:56:19,440 --> 06:56:21,638 let's go ahead and test it so I'm over 9875 06:56:21,638 --> 06:56:23,958 here in the Thunder client tab again 9876 06:56:23,958 --> 06:56:25,120 because I'm using the Thunder client 9877 06:56:25,120 --> 06:56:27,160 plug-in and I'm going to click new 9878 06:56:27,160 --> 06:56:29,360 request and we're going to make a 9879 06:56:29,360 --> 06:56:31,240 request to 9880 06:56:31,240 --> 06:56:34,478 http SL localhost right we want to make 9881 06:56:34,478 --> 06:56:36,760 a request to our own machine on the port 9882 06:56:36,760 --> 06:56:39,080 that we running on which I believe is 9883 06:56:39,080 --> 06:56:41,798 8080 okay with that let's go ahead and 9884 06:56:41,798 --> 06:56:44,280 start up our 9885 06:56:47,878 --> 06:56:50,798 server okay server starting on port 8080 9886 06:56:50,798 --> 06:56:53,080 so it should be good now you'll see I 9887 06:56:53,080 --> 06:56:54,798 don't have a new prompt because my my 9888 06:56:54,798 --> 06:56:57,240 server is still running um if I send 9889 06:56:57,240 --> 06:57:00,120 this get request perfect we get a 404 9890 06:57:00,120 --> 06:57:01,760 that's exactly what we'd expect because 9891 06:57:01,760 --> 06:57:03,520 remember in our code we haven't actually 9892 06:57:03,520 --> 06:57:05,638 set up any handlers or anything we just 9893 06:57:05,638 --> 06:57:07,920 have a server running so we're getting a 9894 06:57:07,920 --> 06:57:10,478 404 because we're trying to hit a path 9895 06:57:10,478 --> 06:57:12,878 in this case the root path uh and it 9896 06:57:12,878 --> 06:57:15,520 doesn't have anything any logic there to 9897 06:57:15,520 --> 06:57:18,600 handle that code if we killed our server 9898 06:57:18,600 --> 06:57:20,558 and ran it again we just get a 9899 06:57:20,558 --> 06:57:23,040 connection refused I've configured my 9900 06:57:23,040 --> 06:57:25,558 thunder client to actually store all of 9901 06:57:25,558 --> 06:57:29,558 my tests or my HTTP requests as plain 9902 06:57:29,558 --> 06:57:31,558 text here in the working directory uh 9903 06:57:31,558 --> 06:57:33,398 but I don't want those going into my 9904 06:57:33,398 --> 06:57:34,558 source control so I'm going to go ahead 9905 06:57:34,558 --> 06:57:37,398 and add that to the G ignore thunder- 9906 06:57:37,398 --> 06:57:40,520 tests we'll ignore everything in there 9907 06:57:40,520 --> 06:57:42,958 next let's add a Coors configuration to 9908 06:57:42,958 --> 06:57:44,520 our router so this is so that people can 9909 06:57:44,520 --> 06:57:46,600 make requests to our server from a 9910 06:57:46,600 --> 06:57:48,280 browser and we're going to be using some 9911 06:57:48,280 --> 06:57:50,718 fairly permissive uh configurations here 9912 06:57:50,718 --> 06:57:51,840 and we'll use 9913 06:57:51,840 --> 06:57:56,200 router. use and then we'll pass in this 9914 06:57:56,200 --> 06:57:58,798 cores. Handler configuration this comes 9915 06:57:58,798 --> 06:58:00,200 from that Coors package that we 9916 06:58:00,200 --> 06:58:02,958 installed earlier and let me see what am 9917 06:58:02,958 --> 06:58:04,320 I doing here we need one more 9918 06:58:04,320 --> 06:58:07,000 parentheses there and then I'm going to 9919 06:58:07,000 --> 06:58:09,680 go ahead and vendor this as well so go 9920 06:58:09,680 --> 06:58:13,958 mod tidy go mod 9921 06:58:15,120 --> 06:58:17,478 vendor cool so we should have all of 9922 06:58:17,478 --> 06:58:21,040 that code here in our vendor folder as 9923 06:58:21,040 --> 06:58:24,160 well I'm not going to go too in depth on 9924 06:58:24,160 --> 06:58:25,718 exactly what cores are you can 9925 06:58:25,718 --> 06:58:27,080 definitely go look that up but just to 9926 06:58:27,080 --> 06:58:29,478 give you a high level overview um this 9927 06:58:29,478 --> 06:58:31,320 configuration is essentially telling our 9928 06:58:31,320 --> 06:58:34,320 server to you send a bunch of uh extra 9929 06:58:34,320 --> 06:58:37,680 HTTP headers in our responses that will 9930 06:58:37,680 --> 06:58:41,440 tell browsers hey we allow you to send 9931 06:58:41,440 --> 06:58:44,840 uh you know requests to http or https 9932 06:58:44,840 --> 06:58:46,478 versions We allow you to use these 9933 06:58:46,478 --> 06:58:48,878 methods we allow you to send any headers 9934 06:58:48,878 --> 06:58:50,760 um it's just a way to say hey we're 9935 06:58:50,760 --> 06:58:52,478 going to allow you to do basically 9936 06:58:52,478 --> 06:58:54,878 whatever you want there are ways you can 9937 06:58:54,878 --> 06:58:56,398 tighten up this configuration for 9938 06:58:56,398 --> 06:58:58,600 security purposes but for now we're just 9939 06:58:58,600 --> 06:59:00,320 going to be running our project on our 9940 06:59:00,320 --> 06:59:02,200 local machine so we're going to just 9941 06:59:02,200 --> 06:59:04,280 open it up make it permissive to avoid 9942 06:59:04,280 --> 06:59:06,478 any sort of uh kind of weird testing 9943 06:59:06,478 --> 06:59:08,280 issues if we try to connect to our 9944 06:59:08,280 --> 06:59:11,080 server through a browser This Server 9945 06:59:11,080 --> 06:59:13,200 we're building is going to be a Json 9946 06:59:13,200 --> 06:59:15,600 rest API which means all of the request 9947 06:59:15,600 --> 06:59:17,520 bodies coming in and response bodies 9948 06:59:17,520 --> 06:59:21,080 going back will have a Json format so 9949 06:59:21,080 --> 06:59:23,520 let's create a little helper function 9950 06:59:23,520 --> 06:59:25,440 that will make it easier to send Json 9951 06:59:25,440 --> 06:59:26,840 responses so I'm going to create a new 9952 06:59:26,840 --> 06:59:28,798 file call it json. go it's going to be 9953 06:59:28,798 --> 06:59:30,040 in the main 9954 06:59:30,040 --> 06:59:32,520 package and the function sign is going 9955 06:59:32,520 --> 06:59:33,878 to look like this so we've got a 9956 06:59:33,878 --> 06:59:35,120 function we're calling it respond with 9957 06:59:35,120 --> 06:59:38,240 Json it takes as input a response writer 9958 06:59:38,240 --> 06:59:40,520 this is the same HTTP response riter 9959 06:59:40,520 --> 06:59:43,520 that uh HTTP handlers Ingo use it's 9960 06:59:43,520 --> 06:59:45,718 exposed by the standard Library um it 9961 06:59:45,718 --> 06:59:48,280 will take a code so this is the status 9962 06:59:48,280 --> 06:59:49,718 code we're going to respond with and 9963 06:59:49,718 --> 06:59:51,760 then we'll take an interface which is 9964 06:59:51,760 --> 06:59:54,520 just something that we can Marshall to 9965 06:59:54,520 --> 06:59:56,840 um a Json structure the first thing the 9966 06:59:56,840 --> 06:59:58,958 function will do is Marshall the payload 9967 06:59:58,958 --> 07:00:02,200 into a Json object or a Json string and 9968 07:00:02,200 --> 07:00:04,000 the way we do that is with the standard 9969 07:00:04,000 --> 07:00:06,760 Library so we data and error equals 9970 07:00:06,760 --> 07:00:08,120 json. 9971 07:00:08,120 --> 07:00:10,878 Marshall and we pass in the 9972 07:00:10,878 --> 07:00:13,320 payload so this function will attempt to 9973 07:00:13,320 --> 07:00:16,240 Marshall uh whatever it's given into a 9974 07:00:16,240 --> 07:00:18,760 Json string and it will return it as 9975 07:00:18,760 --> 07:00:20,240 bytes and the reason it returns it as 9976 07:00:20,240 --> 07:00:21,958 bytes is so that we can write it in a 9977 07:00:21,958 --> 07:00:24,360 binary format directly to the HTTP 9978 07:00:24,360 --> 07:00:26,558 response uh which is pretty convenient 9979 07:00:26,558 --> 07:00:28,440 if that fails for whatever 9980 07:00:28,440 --> 07:00:32,120 reason then what we'll do 9981 07:00:32,120 --> 07:00:35,160 is we'll write a header to the response 9982 07:00:35,160 --> 07:00:36,878 and we'll use status code 500 we'll say 9983 07:00:36,878 --> 07:00:38,798 something went wrong on our end right 9984 07:00:38,798 --> 07:00:40,680 internal service error or internal 9985 07:00:40,680 --> 07:00:43,040 server error um and then we'll just 9986 07:00:43,040 --> 07:00:45,280 return from the function and actually if 9987 07:00:45,280 --> 07:00:46,718 something goes wrong we should probably 9988 07:00:46,718 --> 07:00:49,320 log it um as well on the server side so 9989 07:00:49,320 --> 07:00:51,520 that we can see our own logs and see hey 9990 07:00:51,520 --> 07:00:53,320 we tried to do something in a broke uh 9991 07:00:53,320 --> 07:00:56,638 so we'll do log dot print 9992 07:00:56,638 --> 07:01:00,080 line failed to 9993 07:01:00,080 --> 07:01:02,878 Marshall Json respon 9994 07:01:02,878 --> 07:01:06,718 response and let's print the 9995 07:01:06,760 --> 07:01:08,958 response or let's print what we tried to 9996 07:01:08,958 --> 07:01:11,440 Marshall that's probably more more 9997 07:01:11,440 --> 07:01:13,160 interesting we'll use print F so that we 9998 07:01:13,160 --> 07:01:15,718 can interpolate that value there um next 9999 07:01:15,718 --> 07:01:17,878 we're going to need to add a header to 10000 07:01:17,878 --> 07:01:18,878 the response to say that we're 10001 07:01:18,878 --> 07:01:20,798 responding with Json data so we'll do 10002 07:01:20,798 --> 07:01:23,718 W.R 10003 07:01:24,478 --> 07:01:27,160 header and or not right header I'm sorry 10004 07:01:27,160 --> 07:01:29,958 uh w. 10005 07:01:30,240 --> 07:01:32,958 headers do it 10006 07:01:32,958 --> 07:01:37,680 header do add and we want to add the 10007 07:01:37,680 --> 07:01:41,040 content type key so content 10008 07:01:41,040 --> 07:01:43,840 type and the key will be or the value 10009 07:01:43,840 --> 07:01:47,398 will be application Json so this adds a 10010 07:01:47,398 --> 07:01:49,160 response header to the HTTP request 10011 07:01:49,160 --> 07:01:50,680 saying hey we're responding with a 10012 07:01:50,680 --> 07:01:53,240 content type of application Json which 10013 07:01:53,240 --> 07:01:55,878 is the standard of value for Json 10014 07:01:55,878 --> 07:01:58,240 responses um and then we should be able 10015 07:01:58,240 --> 07:02:02,680 to uh write the status code so we do w . 10016 07:02:02,680 --> 07:02:06,360 WR header 200 so everything went well 10017 07:02:06,360 --> 07:02:07,920 and then we need to write the data 10018 07:02:07,920 --> 07:02:12,600 itself so w. write and pass in the Json 10019 07:02:12,600 --> 07:02:15,080 data this will write the response body 10020 07:02:15,080 --> 07:02:16,760 now that we have a way to respond with 10021 07:02:16,760 --> 07:02:18,760 some Json data let's create an HTTP 10022 07:02:18,760 --> 07:02:21,320 Handler that does that so we'll do 10023 07:02:21,320 --> 07:02:23,840 handlers or 10024 07:02:23,840 --> 07:02:26,600 Handler 10025 07:02:26,600 --> 07:02:28,878 Readiness again this will be in the main 10026 07:02:28,878 --> 07:02:30,958 package and we're going to create a new 10027 07:02:30,958 --> 07:02:33,200 function 10028 07:02:33,200 --> 07:02:36,160 called Handler Readiness and this is a 10029 07:02:36,160 --> 07:02:38,240 very specific function signature this is 10030 07:02:38,240 --> 07:02:40,040 the function signature that you have to 10031 07:02:40,040 --> 07:02:42,840 use if you want to Define an HTTP 10032 07:02:42,840 --> 07:02:44,638 Handler in the way that the goh standard 10033 07:02:44,638 --> 07:02:47,280 Library expects so it always takes a 10034 07:02:47,280 --> 07:02:49,718 response writer as the first parameter 10035 07:02:49,718 --> 07:02:52,440 and a pointer to an HTTP request as the 10036 07:02:52,440 --> 07:02:54,718 second parameter and then in the body of 10037 07:02:54,718 --> 07:02:56,760 this Handler we can just call our 10038 07:02:56,760 --> 07:02:59,760 respond with Json function so we'll say 10039 07:02:59,760 --> 07:03:03,120 respond with Json we'll pass in that 10040 07:03:03,120 --> 07:03:06,280 HTTP response writer we want to respond 10041 07:03:06,280 --> 07:03:11,478 with a 200 status code and some some 10042 07:03:11,478 --> 07:03:14,440 response payload in this case all we 10043 07:03:14,440 --> 07:03:17,080 care about is the 200 okay status code 10044 07:03:17,080 --> 07:03:18,160 so I'm actually just going to respond 10045 07:03:18,160 --> 07:03:19,520 with an empty struct which should 10046 07:03:19,520 --> 07:03:23,120 Marshall to kind of an empty Json object 10047 07:03:23,120 --> 07:03:24,840 and now that I'm writing this I realized 10048 07:03:24,840 --> 07:03:26,320 that we actually made a mistake or I 10049 07:03:26,320 --> 07:03:29,478 made a mistake in the Json uh respond 10050 07:03:29,478 --> 07:03:32,440 with Json code we should pass in uh we 10051 07:03:32,440 --> 07:03:34,680 should use the pting Response Code 10052 07:03:34,680 --> 07:03:36,638 instead of hardcoding the 200 so if 10053 07:03:36,638 --> 07:03:38,520 everything goes right we'll use the code 10054 07:03:38,520 --> 07:03:42,080 given okay now with that we need to hook 10055 07:03:42,080 --> 07:03:45,440 up our Handler Now using the chi router 10056 07:03:45,440 --> 07:03:47,558 what we do is we hook up a an HTTP 10057 07:03:47,558 --> 07:03:49,680 Handler which is this function to a 10058 07:03:49,680 --> 07:03:53,398 specific HTTP method and path okay so 10059 07:03:53,398 --> 07:03:54,840 the way we're going to do that is I'm 10060 07:03:54,840 --> 07:03:57,160 going to create a new router so V1 10061 07:03:57,160 --> 07:04:00,878 router and we'll use that same chi. new 10062 07:04:00,878 --> 07:04:02,558 router to do it 10063 07:04:02,558 --> 07:04:06,080 and I'm going to specify V1 10064 07:04:06,080 --> 07:04:07,600 router. 10065 07:04:07,600 --> 07:04:11,280 handle handle Funk excuse me I want to 10066 07:04:11,280 --> 07:04:13,840 handle the slash ready 10067 07:04:13,840 --> 07:04:17,200 path and I want to handle it with this 10068 07:04:17,200 --> 07:04:20,440 Handler Readiness function okay so we're 10069 07:04:20,440 --> 07:04:22,638 we're connecting the Handler Readiness 10070 07:04:22,638 --> 07:04:25,478 function to the slash ready path and the 10071 07:04:25,478 --> 07:04:27,798 reason I created this new V1 router is 10072 07:04:27,798 --> 07:04:30,320 because I'm going to mount that so I can 10073 07:04:30,320 --> 07:04:33,320 do router. Mount 10074 07:04:33,320 --> 07:04:35,680 count to the 10075 07:04:35,680 --> 07:04:40,360 slv1 path okay so I'm nesting a V1 10076 07:04:40,360 --> 07:04:43,200 router under the slv1 path and I'm 10077 07:04:43,200 --> 07:04:44,920 hooking up the Readiness Handler at the 10078 07:04:44,920 --> 07:04:48,360 SL ready path so the full path for this 10079 07:04:48,360 --> 07:04:51,320 request will be slv1 SL ready and that's 10080 07:04:51,320 --> 07:04:53,120 just so that if we make breaking changes 10081 07:04:53,120 --> 07:04:55,440 in the future we can kind of have two 10082 07:04:55,440 --> 07:04:57,600 different handlers one under version one 10083 07:04:57,600 --> 07:04:59,680 and one under version two for our rest 10084 07:04:59,680 --> 07:05:02,200 API this is fairly standard practice 10085 07:05:02,200 --> 07:05:04,718 and actually I'm going to name this path 10086 07:05:04,718 --> 07:05:08,520 health health Z that's just a habit uh 10087 07:05:08,520 --> 07:05:09,680 that I'm bringing with me from 10088 07:05:09,680 --> 07:05:11,478 kubernetes land it's pretty standard to 10089 07:05:11,478 --> 07:05:14,398 have a SL Health Z path um that you can 10090 07:05:14,398 --> 07:05:16,360 hit to see if your server is live and 10091 07:05:16,360 --> 07:05:18,280 running so that's the purpose of this 10092 07:05:18,280 --> 07:05:20,478 Handler it should just respond if the 10093 07:05:20,478 --> 07:05:22,320 server is alive and running and 10094 07:05:22,320 --> 07:05:23,958 everything's good okay so let's go ahead 10095 07:05:23,958 --> 07:05:25,798 and run the server and make sure it's 10096 07:05:25,798 --> 07:05:28,280 doing what we'd expect so go build and 10097 07:05:28,280 --> 07:05:31,798 slash RSS a that starts up the server 10098 07:05:31,798 --> 07:05:33,878 and then we can open up thunder 10099 07:05:33,878 --> 07:05:36,080 client and now instead of making a 10100 07:05:36,080 --> 07:05:37,760 request to the root which we'd expect to 10101 07:05:37,760 --> 07:05:41,200 get a 404 from we'll do 10102 07:05:41,200 --> 07:05:45,600 slv1 healz and make that get request and 10103 07:05:45,600 --> 07:05:48,398 we get the 200 now here's the weird 10104 07:05:48,398 --> 07:05:50,958 thing if I change this to a post request 10105 07:05:50,958 --> 07:05:54,398 and I make that I actually still get a 10106 07:05:54,398 --> 07:05:56,280 200 but that's not really Our intention 10107 07:05:56,280 --> 07:05:58,080 the health Z endpoint should really only 10108 07:05:58,080 --> 07:06:00,120 be accessible by get request so I'm 10109 07:06:00,120 --> 07:06:01,878 going to make an update here rather than 10110 07:06:01,878 --> 07:06:03,878 using the V1 router. handle Funk I'm 10111 07:06:03,878 --> 07:06:06,440 going to use V1 router. getet and this 10112 07:06:06,440 --> 07:06:09,718 will scope the Handler to only fire on 10113 07:06:09,718 --> 07:06:12,120 get requests okay with that let's go 10114 07:06:12,120 --> 07:06:13,760 ahead and rebuild our 10115 07:06:13,760 --> 07:06:18,240 server and check again post should fail 10116 07:06:18,240 --> 07:06:20,600 method not allowed perfect but the get 10117 07:06:20,600 --> 07:06:23,320 request should still work so we have a 10118 07:06:23,320 --> 07:06:25,040 nice helper function for responding with 10119 07:06:25,040 --> 07:06:27,320 arbitrary Json now I want one for 10120 07:06:27,320 --> 07:06:29,600 responding with arbitrary error messages 10121 07:06:29,600 --> 07:06:32,280 so let's do function respond with there 10122 07:06:32,280 --> 07:06:33,840 um it will look very similar but instead 10123 07:06:33,840 --> 07:06:35,240 of taking a payload which is an 10124 07:06:35,240 --> 07:06:37,680 interface it will take a message string 10125 07:06:37,680 --> 07:06:38,840 and this function is basically just 10126 07:06:38,840 --> 07:06:41,478 going to format that message into a 10127 07:06:41,478 --> 07:06:45,360 consistent uh Json object every single 10128 07:06:45,360 --> 07:06:47,760 time okay uh first thing we're going to 10129 07:06:47,760 --> 07:06:50,360 do is say if the code is greater than 10130 07:06:50,360 --> 07:06:52,600 499 we're going to log a message and 10131 07:06:52,600 --> 07:06:56,200 that's because uh error codes in the 400 10132 07:06:56,200 --> 07:06:58,680 range are client side errors so we don't 10133 07:06:58,680 --> 07:07:00,120 really need to know about them it just 10134 07:07:00,120 --> 07:07:02,120 means someone's using our API in a weird 10135 07:07:02,120 --> 07:07:03,840 way um but we do need to know whenever 10136 07:07:03,840 --> 07:07:06,440 we're sering we're responding with a 500 10137 07:07:06,440 --> 07:07:08,320 level error code because that means we 10138 07:07:08,320 --> 07:07:09,798 have a bug on our end and we should 10139 07:07:09,798 --> 07:07:12,760 probably go fix it so we'll do log. 10140 07:07:12,760 --> 07:07:17,760 print line responding with 500 level 10141 07:07:17,760 --> 07:07:19,878 error and we'll just tack the message 10142 07:07:19,878 --> 07:07:23,240 itself on there okay cool after we do 10143 07:07:23,240 --> 07:07:26,360 that logging um we'll use the respond 10144 07:07:26,360 --> 07:07:28,958 with Json function uh but we'll be 10145 07:07:28,958 --> 07:07:30,240 responding with a 10146 07:07:30,240 --> 07:07:32,080 specific uh 10147 07:07:32,080 --> 07:07:34,360 structure of Json uh so let's go ahead 10148 07:07:34,360 --> 07:07:37,718 and Define that as a struct so type um 10149 07:07:37,718 --> 07:07:39,398 air 10150 07:07:39,398 --> 07:07:41,878 response is a struct and it has one 10151 07:07:41,878 --> 07:07:45,240 field error which just a string and 10152 07:07:45,240 --> 07:07:48,280 we'll add this Json tag to just say this 10153 07:07:48,280 --> 07:07:50,478 the key that this should Marcel to is 10154 07:07:50,478 --> 07:07:54,440 error so in go we typically take a 10155 07:07:54,440 --> 07:07:57,760 struct and add these Json reflect tags 10156 07:07:57,760 --> 07:08:01,200 to it to specify how we want this json. 10157 07:08:01,200 --> 07:08:03,798 Mar function or on the other side the 10158 07:08:03,798 --> 07:08:07,558 json. unmarshal function uh to kind of 10159 07:08:07,558 --> 07:08:11,040 convert this struct into a Json object 10160 07:08:11,040 --> 07:08:13,320 so in this case we're saying I have an 10161 07:08:13,320 --> 07:08:16,000 error field it's string and I want the 10162 07:08:16,000 --> 07:08:18,440 key for the field to be error so this 10163 07:08:18,440 --> 07:08:20,920 struct will Marshall into a Json object 10164 07:08:20,920 --> 07:08:24,920 that looks kind of like uh like 10165 07:08:25,280 --> 07:08:27,040 this 10166 07:08:27,040 --> 07:08:33,440 error you something went wrong 10167 07:08:33,600 --> 07:08:36,040 right it wouldn't have actually wouldn't 10168 07:08:36,040 --> 07:08:38,638 have that but it would look like that 10169 07:08:38,638 --> 07:08:41,600 okay and we'll see that in just a second 10170 07:08:41,600 --> 07:08:43,878 okay so now we get to respond with Json 10171 07:08:43,878 --> 07:08:46,760 we pass in the response writer a the 10172 07:08:46,760 --> 07:08:48,760 same code that we were given and then 10173 07:08:48,760 --> 07:08:51,958 we'll just respond with an error 10174 07:08:51,958 --> 07:08:54,718 response and the error message will be 10175 07:08:54,718 --> 07:08:56,680 the message that we were 10176 07:08:56,680 --> 07:09:00,000 given okay let's hook this up to another 10177 07:09:00,000 --> 07:09:05,798 Handler so here we can do V1 router. 10178 07:09:05,798 --> 07:09:09,760 getet we'll create an error endpoint and 10179 07:09:09,760 --> 07:09:13,080 oh I need I need an actual Handler so 10180 07:09:13,080 --> 07:09:16,478 we'll create a new one called 10181 07:09:16,600 --> 07:09:19,600 Handler 10182 07:09:20,398 --> 07:09:24,558 error Handler error and we'll respond 10183 07:09:24,558 --> 07:09:26,638 with an error instead of passing in an 10184 07:09:26,638 --> 07:09:29,360 empty struct we'll 10185 07:09:29,360 --> 07:09:32,360 say something when 10186 07:09:32,360 --> 07:09:36,160 wrong and we'll respond with a 400 10187 07:09:36,160 --> 07:09:39,520 status code client error right okay now 10188 07:09:39,520 --> 07:09:41,280 we can hook up this error 10189 07:09:41,280 --> 07:09:45,160 Handler here it will only work on get 10190 07:09:45,160 --> 07:09:47,798 requests that seems reasonable and 10191 07:09:47,798 --> 07:09:50,000 basically it's just going to call that 10192 07:09:50,000 --> 07:09:51,280 respond with error function so it'll be 10193 07:09:51,280 --> 07:09:53,440 a good way to test 10194 07:09:53,440 --> 07:09:59,000 that okay let's go ahead and rebuild the 10195 07:09:59,040 --> 07:10:02,080 server nope what did we screw up 10196 07:10:02,080 --> 07:10:05,040 routing pattern must begin with Slash ah 10197 07:10:05,040 --> 07:10:07,718 let's go fix 10198 07:10:08,040 --> 07:10:10,718 that so you can see here we've got SL 10199 07:10:10,718 --> 07:10:13,718 Health zv1 we need to start these with a 10200 07:10:13,718 --> 07:10:16,200 slash it's just the way the chai rou or 10201 07:10:16,200 --> 07:10:18,920 the chi router 10202 07:10:19,120 --> 07:10:22,160 works cool um let's go open up the 10203 07:10:22,160 --> 07:10:24,280 Thunder client and send a 10204 07:10:24,280 --> 07:10:27,718 request to the slash errror 10205 07:10:27,718 --> 07:10:31,360 Handler cool we get the 400 bad request 10206 07:10:31,360 --> 07:10:34,638 status code and this is that Json body 10207 07:10:34,638 --> 07:10:37,240 um so every single time that we need to 10208 07:10:37,240 --> 07:10:39,280 return an error from our server now we 10209 07:10:39,280 --> 07:10:40,718 can just use this function and it will 10210 07:10:40,718 --> 07:10:43,398 always use this consistent error format 10211 07:10:43,398 --> 07:10:44,680 which is great because we can throw this 10212 07:10:44,680 --> 07:10:46,120 in our documentation and just tell all 10213 07:10:46,120 --> 07:10:49,120 of the users of our API hey this is what 10214 07:10:49,120 --> 07:10:50,798 you should expect when something goes 10215 07:10:50,798 --> 07:10:52,680 wrong now that we have a little bit of 10216 07:10:52,680 --> 07:10:54,200 our boiler plate set up I'm going to 10217 07:10:54,200 --> 07:10:56,200 take the opportunity to commit all of 10218 07:10:56,200 --> 07:10:58,798 this to get uh so that I don't lose it 10219 07:10:58,798 --> 07:11:02,558 um I will say that I generally recommend 10220 07:11:02,558 --> 07:11:04,680 committing the vendor folder so you can 10221 07:11:04,680 --> 07:11:06,040 think of the vendor folder kind of like 10222 07:11:06,040 --> 07:11:07,600 the node modules folder if you're 10223 07:11:07,600 --> 07:11:09,520 familiar with JavaScript land and in 10224 07:11:09,520 --> 07:11:11,040 JavaScript you would never commit it 10225 07:11:11,040 --> 07:11:13,798 it's way too big um but in go we 10226 07:11:13,798 --> 07:11:15,440 typically don't have all that many 10227 07:11:15,440 --> 07:11:17,520 dependencies so it's actually perfectly 10228 07:11:17,520 --> 07:11:20,120 fine to commit the vendor folder in most 10229 07:11:20,120 --> 07:11:22,160 scenarios and I'd even recommend it so 10230 07:11:22,160 --> 07:11:24,200 I'm going to go ahead and add that and 10231 07:11:24,200 --> 07:11:26,200 commit 10232 07:11:26,200 --> 07:11:28,878 it we'll say 10233 07:11:28,878 --> 07:11:32,000 boilerplate or http 10234 07:11:32,000 --> 07:11:33,520 server 10235 07:11:33,520 --> 07:11:35,840 complete for this project we're going to 10236 07:11:35,840 --> 07:11:38,478 use postgress as our SQL database it's a 10237 07:11:38,478 --> 07:11:40,160 production ready database in fact it's 10238 07:11:40,160 --> 07:11:42,440 the one I used to build 10239 07:11:42,440 --> 07:11:45,280 boot. you're going to need to install 10240 07:11:45,280 --> 07:11:47,478 postgress on your local machine make 10241 07:11:47,478 --> 07:11:49,798 sure that the postgress server is up and 10242 07:11:49,798 --> 07:11:51,878 running and that you have a client 10243 07:11:51,878 --> 07:11:54,160 installed that you can use to make kind 10244 07:11:54,160 --> 07:11:57,520 of oneoff SQL queries against it I have 10245 07:11:57,520 --> 07:11:59,200 detailed instructions on how to do all 10246 07:11:59,200 --> 07:12:01,360 of that in the text instructions for 10247 07:12:01,360 --> 07:12:03,760 this project over on boot. so again go 10248 07:12:03,760 --> 07:12:05,280 check those out if you need to figure 10249 07:12:05,280 --> 07:12:08,080 out how to install postgress locally and 10250 07:12:08,080 --> 07:12:10,280 get a postgress client up and running on 10251 07:12:10,280 --> 07:12:12,680 your machine I use PG admin so that's 10252 07:12:12,680 --> 07:12:14,638 what you'll see me using in this 10253 07:12:14,638 --> 07:12:16,920 tutorial so if you followed those 10254 07:12:16,920 --> 07:12:18,320 instructions then you should have a 10255 07:12:18,320 --> 07:12:19,920 postgress server running on your local 10256 07:12:19,920 --> 07:12:22,680 machine and a postgress client installed 10257 07:12:22,680 --> 07:12:24,760 again I use PG admin that's what you're 10258 07:12:24,760 --> 07:12:28,558 seeing here on the screen okay so 10259 07:12:28,558 --> 07:12:30,798 because postgress is running locally I 10260 07:12:30,798 --> 07:12:33,920 have this Local Host server here in PG 10261 07:12:33,920 --> 07:12:35,798 admin that I've connected to again 10262 07:12:35,798 --> 07:12:37,160 that's the postgress server running on 10263 07:12:37,160 --> 07:12:39,398 my own machine and under databases I 10264 07:12:39,398 --> 07:12:41,160 have kind of the built-in postgress 10265 07:12:41,160 --> 07:12:43,120 database but I want to create a new 10266 07:12:43,120 --> 07:12:44,718 database that we're going to use for 10267 07:12:44,718 --> 07:12:47,200 this project so um in this case I'm just 10268 07:12:47,200 --> 07:12:49,840 going to name it uh RSS 10269 07:12:49,840 --> 07:12:52,958 a and we'll create that 10270 07:12:52,958 --> 07:12:56,200 database and then here within the RSS a 10271 07:12:56,200 --> 07:12:59,878 database as long as the uh kind of icons 10272 07:12:59,878 --> 07:13:02,320 are gold then you're connected and 10273 07:13:02,320 --> 07:13:04,360 everything is working at least up to 10274 07:13:04,360 --> 07:13:06,600 this point let's run a quick query 10275 07:13:06,600 --> 07:13:08,360 against the database just to really make 10276 07:13:08,360 --> 07:13:09,878 sure everything's working so I'm right 10277 07:13:09,878 --> 07:13:12,558 clicking here on the RSS a database and 10278 07:13:12,558 --> 07:13:15,478 I'm going to click query 10279 07:13:15,478 --> 07:13:17,958 tool and from this tool I should be able 10280 07:13:17,958 --> 07:13:19,718 to just write some raw SQL so I'm going 10281 07:13:19,718 --> 07:13:21,200 to go ahead and do a 10282 07:13:21,200 --> 07:13:24,360 select version this should just return 10283 07:13:24,360 --> 07:13:25,840 the current version of postgress that 10284 07:13:25,840 --> 07:13:29,878 I'm using I'm on version 14.7 and as 10285 07:13:29,878 --> 07:13:31,638 long as you're on something 10286 07:13:31,638 --> 07:13:34,920 14.7 or newer you should be good to go 10287 07:13:34,920 --> 07:13:36,520 now it's important to keep in mind here 10288 07:13:36,520 --> 07:13:39,200 that PG admin is just a client for 10289 07:13:39,200 --> 07:13:41,680 interacting with an SQL database right 10290 07:13:41,680 --> 07:13:44,440 we're able to write raw SQL code here 10291 07:13:44,440 --> 07:13:47,520 and run it against our database server 10292 07:13:47,520 --> 07:13:49,080 if you think about it kind of in an 10293 07:13:49,080 --> 07:13:51,638 analogous sense PG admin is basically 10294 07:13:51,638 --> 07:13:53,000 just the same thing as the Thunder 10295 07:13:53,000 --> 07:13:55,478 client where the Thunder client is a 10296 07:13:55,478 --> 07:13:57,958 client for running one-off HTTP requests 10297 07:13:57,958 --> 07:14:01,160 against our server PG admin is a client 10298 07:14:01,160 --> 07:14:04,440 for running oneoff SQL requests or SQL 10299 07:14:04,440 --> 07:14:07,320 queries against our database directly 10300 07:14:07,320 --> 07:14:08,840 next we're going to install two command 10301 07:14:08,840 --> 07:14:10,840 line tools that will allow us to work 10302 07:14:10,840 --> 07:14:14,240 with SQL databases from our go code much 10303 07:14:14,240 --> 07:14:16,398 easier now these aren't fully-fledged 10304 07:14:16,398 --> 07:14:18,798 orms if you're familiar with that term 10305 07:14:18,798 --> 07:14:20,520 these are kind of lightweight libraries 10306 07:14:20,520 --> 07:14:22,478 that allow us to work with SQL databases 10307 07:14:22,478 --> 07:14:24,200 using the standard library and just sort 10308 07:14:24,200 --> 07:14:26,080 of streamline the process for us the 10309 07:14:26,080 --> 07:14:27,440 first one is called 10310 07:14:27,440 --> 07:14:30,280 sqlc and again you can find all of these 10311 07:14:30,280 --> 07:14:32,080 commands in in the text instructions 10312 07:14:32,080 --> 07:14:34,160 over on bootd so be sure to be following 10313 07:14:34,160 --> 07:14:35,760 along over there but we're going to use 10314 07:14:35,760 --> 07:14:39,360 the go install command to go grab uh 10315 07:14:39,360 --> 07:14:42,120 sqlc and install it into our command 10316 07:14:42,120 --> 07:14:44,120 line once that's done you should be able 10317 07:14:44,120 --> 07:14:45,240 to just run 10318 07:14:45,240 --> 07:14:49,000 sqlc version to make sure it's working 10319 07:14:49,000 --> 07:14:52,120 next we'll install Goose the same way so 10320 07:14:52,120 --> 07:14:55,280 go install um and then the installation 10321 07:14:55,280 --> 07:14:58,240 path for goose again uh that link is 10322 07:14:58,240 --> 07:15:00,398 over in the text instructions and then 10323 07:15:00,398 --> 07:15:01,840 you can make sure that goose is 10324 07:15:01,840 --> 07:15:03,360 installed working correctly by typing 10325 07:15:03,360 --> 07:15:06,760 Goose Das version the great thing about 10326 07:15:06,760 --> 07:15:09,440 sqlc and goose is that they work based 10327 07:15:09,440 --> 07:15:12,320 on Raw SQL there's no kind of fancy 10328 07:15:12,320 --> 07:15:14,240 query language that's unique to those 10329 07:15:14,240 --> 07:15:16,280 tools we can just write SQL queries and 10330 07:15:16,280 --> 07:15:17,798 we're going to store all of that in our 10331 07:15:17,798 --> 07:15:19,958 repository so I'm going to create a new 10332 07:15:19,958 --> 07:15:22,520 folder is called SQL and in there I'll 10333 07:15:22,520 --> 07:15:25,520 create a new directory called schema and 10334 07:15:25,520 --> 07:15:27,320 this is where we'll store all of our 10335 07:15:27,320 --> 07:15:29,120 table definitions um or more 10336 07:15:29,120 --> 07:15:32,398 specifically our migrations so uh we'll 10337 07:15:32,398 --> 07:15:34,718 start with a users table and the way 10338 07:15:34,718 --> 07:15:37,000 Goose works is it runs the migrations in 10339 07:15:37,000 --> 07:15:39,280 order so we're going to start with 10340 07:15:39,280 --> 07:15:43,558 a01 migration and we'll call it users. 10341 07:15:43,558 --> 07:15:46,798 SQL from a very high level the way that 10342 07:15:46,798 --> 07:15:49,320 database migrations work is they have an 10343 07:15:49,320 --> 07:15:52,000 up and a down statement so for example 10344 07:15:52,000 --> 07:15:54,160 here we're creating a users table the up 10345 07:15:54,160 --> 07:15:56,240 statement will just create a new users 10346 07:15:56,240 --> 07:15:58,680 table and the down statement will delete 10347 07:15:58,680 --> 07:16:01,200 that same table so any down statement 10348 07:16:01,200 --> 07:16:03,440 should just undo the operation of the up 10349 07:16:03,440 --> 07:16:05,600 statement and that just makes it easy to 10350 07:16:05,600 --> 07:16:08,478 roll back changes to our database schema 10351 07:16:08,478 --> 07:16:11,000 if we ever need to the goose command 10352 07:16:11,000 --> 07:16:13,320 line tool Works based off of SQL 10353 07:16:13,320 --> 07:16:15,080 comments so we'll start with a comment 10354 07:16:15,080 --> 07:16:20,080 Das Dash plus Goose 10355 07:16:20,200 --> 07:16:25,958 up and dash dash plus goose down and 10356 07:16:25,958 --> 07:16:28,240 then anything we type here uh will be 10357 07:16:28,240 --> 07:16:30,240 considered an up migration and anything 10358 07:16:30,240 --> 07:16:32,760 here will be a down migration so let's 10359 07:16:32,760 --> 07:16:34,520 start with the up migration it's going 10360 07:16:34,520 --> 07:16:35,558 to be 10361 07:16:35,558 --> 07:16:38,840 create create table 10362 07:16:38,840 --> 07:16:41,120 users and the first field will just be 10363 07:16:41,120 --> 07:16:43,320 called ID it'll be a uyu ID a 10364 07:16:43,320 --> 07:16:45,840 universally unique identifier um I 10365 07:16:45,840 --> 07:16:49,120 prefer uu IDs to integer primary keys 10366 07:16:49,120 --> 07:16:51,360 for a number of reasons um I'll link a 10367 07:16:51,360 --> 07:16:54,040 blog post down in the description below 10368 07:16:54,040 --> 07:16:56,878 um and that's just going to be a primary 10369 07:16:56,878 --> 07:16:58,798 key uh next we're going to need a 10370 07:16:58,798 --> 07:17:02,360 created at which is a a 10371 07:17:02,360 --> 07:17:06,040 timestamp not null we must have must 10372 07:17:06,040 --> 07:17:08,638 have a created at must have an updated 10373 07:17:08,638 --> 07:17:11,280 at same 10374 07:17:12,200 --> 07:17:14,600 thing and then a user will also have a 10375 07:17:14,600 --> 07:17:17,680 name and we'll just make that a text 10376 07:17:17,680 --> 07:17:21,520 field again let's say that's not null I 10377 07:17:21,520 --> 07:17:23,398 need to remember to terminate my SQL 10378 07:17:23,398 --> 07:17:25,840 statements with a semicolon and for the 10379 07:17:25,840 --> 07:17:27,798 down M migration um it's pretty simple 10380 07:17:27,798 --> 07:17:30,520 we'll just drop the table so drop table 10381 07:17:30,520 --> 07:17:33,000 user users all right let's run our 10382 07:17:33,000 --> 07:17:35,120 migration but first we're going to need 10383 07:17:35,120 --> 07:17:36,440 to be able to connect to our local 10384 07:17:36,440 --> 07:17:38,840 database from our program and from our 10385 07:17:38,840 --> 07:17:41,360 command line so uh very first thing is 10386 07:17:41,360 --> 07:17:44,520 we'll need a DB 10387 07:17:44,520 --> 07:17:47,798 URL and we'll set it equal to the URL 10388 07:17:47,798 --> 07:17:49,638 that we use to connect to our local 10389 07:17:49,638 --> 07:17:51,240 postgress server so this isn't to 10390 07:17:51,240 --> 07:17:53,718 connect to PG admin this is the same 10391 07:17:53,718 --> 07:17:56,000 connection string that PG admin uses to 10392 07:17:56,000 --> 07:17:57,680 connect to the database server we want 10393 07:17:57,680 --> 07:18:00,160 to go directly to the database so it's 10394 07:18:00,160 --> 07:18:01,558 going to look something like this 10395 07:18:01,558 --> 07:18:05,680 postgress is the protocol so colon SL um 10396 07:18:05,680 --> 07:18:08,040 again this is just a URL um and then we 10397 07:18:08,040 --> 07:18:10,320 have the authentication part uh which in 10398 07:18:10,320 --> 07:18:13,638 my case is Wags Lane because that's the 10399 07:18:13,638 --> 07:18:17,878 uh user on my machine um and then colon 10400 07:18:17,878 --> 07:18:20,200 and then password if you have a password 10401 07:18:20,200 --> 07:18:22,160 for your local database this is where it 10402 07:18:22,160 --> 07:18:24,120 goes I actually did not set one up 10403 07:18:24,120 --> 07:18:25,680 because it's just my local 10404 07:18:25,680 --> 07:18:28,440 database and it's going to be at Local 10405 07:18:28,440 --> 07:18:31,360 Host col5 10406 07:18:31,360 --> 07:18:34,958 432 which is the standard port for 10407 07:18:34,958 --> 07:18:37,398 postgress and the last part of the URL 10408 07:18:37,398 --> 07:18:39,520 is just going to be the database name uh 10409 07:18:39,520 --> 07:18:41,000 that you created so in my case I believe 10410 07:18:41,000 --> 07:18:45,040 it was RSS a okay so your url will 10411 07:18:45,040 --> 07:18:46,558 should look very similar to this with 10412 07:18:46,558 --> 07:18:48,798 maybe you know the username the database 10413 07:18:48,798 --> 07:18:50,320 name um something like that could be 10414 07:18:50,320 --> 07:18:52,320 could potentially be swapped out on your 10415 07:18:52,320 --> 07:18:56,798 machine okay to run our migration here 10416 07:18:56,798 --> 07:18:59,760 I'm going to copy I'm going to copy this 10417 07:18:59,760 --> 07:19:02,040 database URL 10418 07:19:02,040 --> 07:19:04,320 and then I'm going to CD into this 10419 07:19:04,320 --> 07:19:07,080 directory so CD SQL 10420 07:19:07,080 --> 07:19:09,600 schema and then from here I can run 10421 07:19:09,600 --> 07:19:11,160 Goose 10422 07:19:11,160 --> 07:19:13,360 postgress so I'm telling I'm telling 10423 07:19:13,360 --> 07:19:15,080 Goose that hey I'm using a postgress 10424 07:19:15,080 --> 07:19:16,920 database and then I'll paste in my 10425 07:19:16,920 --> 07:19:17,920 connection 10426 07:19:17,920 --> 07:19:21,040 string and type up so this will run the 10427 07:19:21,040 --> 07:19:24,558 up migration a nasty error here turns 10428 07:19:24,558 --> 07:19:27,120 out I forgot some commas we need to 10429 07:19:27,120 --> 07:19:29,200 separate all of these field names with 10430 07:19:29,200 --> 07:19:33,718 commas cool save that file let's try 10431 07:19:33,718 --> 07:19:38,200 again so we got okay 001 users. SQL no 10432 07:19:38,200 --> 07:19:40,360 more migrations so that should have run 10433 07:19:40,360 --> 07:19:42,200 let's check PG admin to make sure that 10434 07:19:42,200 --> 07:19:44,840 it worked so now over in PG admin under 10435 07:19:44,840 --> 07:19:47,000 my RSS a database I should be able to 10436 07:19:47,000 --> 07:19:52,040 come into the schemas tab the tables tag 10437 07:19:52,040 --> 07:19:54,160 and I can see here that I've now have 10438 07:19:54,160 --> 07:19:56,760 two tables Goose DB version so this is 10439 07:19:56,760 --> 07:19:59,240 an automatic table created and managed 10440 07:19:59,240 --> 07:20:01,080 by goose and then I've got the users 10441 07:20:01,080 --> 07:20:03,000 table that I just created let's go ahead 10442 07:20:03,000 --> 07:20:06,558 and do a select star from users and we 10443 07:20:06,558 --> 07:20:08,680 should just be able to see uh those 10444 07:20:08,680 --> 07:20:10,840 column names come back now let's make 10445 07:20:10,840 --> 07:20:12,798 sure that the down migration works as 10446 07:20:12,798 --> 07:20:15,398 well go ahead and run the exact same 10447 07:20:15,398 --> 07:20:18,000 thing but this time down instead and you 10448 07:20:18,000 --> 07:20:20,320 can see that it down migrated the same 10449 07:20:20,320 --> 07:20:23,440 file now over in PG admin if I 10450 07:20:23,440 --> 07:20:25,878 rightclick on tables and click refresh 10451 07:20:25,878 --> 07:20:27,638 you'll see the users table's gone and 10452 07:20:27,638 --> 07:20:30,000 this query should fail now okay so let's 10453 07:20:30,000 --> 07:20:32,240 reup migrate to get that database table 10454 07:20:32,240 --> 07:20:34,000 created again and then the interesting 10455 07:20:34,000 --> 07:20:35,958 thing about migrations is you can rerun 10456 07:20:35,958 --> 07:20:38,080 the same up migration and you won't get 10457 07:20:38,080 --> 07:20:40,160 any errors because Goose knows that 10458 07:20:40,160 --> 07:20:42,558 you're already migrated up to the most 10459 07:20:42,558 --> 07:20:45,360 recent version of your migrations now 10460 07:20:45,360 --> 07:20:47,680 it's time to write a query so we're 10461 07:20:47,680 --> 07:20:50,320 using sqlc to handle our queries and 10462 07:20:50,320 --> 07:20:52,280 Goose to handle our migrations so to get 10463 07:20:52,280 --> 07:20:55,080 sqlc set up we need to create a new file 10464 07:20:55,080 --> 07:20:57,840 in the root of our project called sqlc 10465 07:20:57,840 --> 07:21:00,000 do yaml I'm going to paste in this 10466 07:21:00,000 --> 07:21:01,680 configuration here basically it's just 10467 07:21:01,680 --> 07:21:04,680 telling sqlc what version we're using um 10468 07:21:04,680 --> 07:21:06,840 what database engine we're using and 10469 07:21:06,840 --> 07:21:09,478 where we're going to store our queries 10470 07:21:09,478 --> 07:21:11,718 the raw SQL for our queries are going to 10471 07:21:11,718 --> 07:21:13,638 live in the SQL directory under a new 10472 07:21:13,638 --> 07:21:16,240 subdirectory called queries we've 10473 07:21:16,240 --> 07:21:19,200 specified that here right and here I'm 10474 07:21:19,200 --> 07:21:20,360 going to create a new file I'm just 10475 07:21:20,360 --> 07:21:24,000 going to call it users. 10476 07:21:24,000 --> 07:21:26,478 SQL and again this is where the SQL will 10477 07:21:26,478 --> 07:21:29,200 live and the way sqlc works is that it 10478 07:21:29,200 --> 07:21:32,040 takes the SQL statements and it 10479 07:21:32,040 --> 07:21:35,558 generates go code Type safe go code that 10480 07:21:35,558 --> 07:21:39,440 matches the SQL every sqlc query starts 10481 07:21:39,440 --> 07:21:42,000 off with a comment that starts with its 10482 07:21:42,000 --> 07:21:45,160 name so name will do a create user 10483 07:21:45,160 --> 07:21:48,878 statement and it returns one record so 10484 07:21:48,878 --> 07:21:51,120 we're saying I want a new function 10485 07:21:51,120 --> 07:21:53,600 called create user oops and it's going 10486 07:21:53,600 --> 07:21:56,558 to return one user that statement will 10487 07:21:56,558 --> 07:22:02,398 be insert into users uh ID created 10488 07:22:02,398 --> 07:22:06,958 Created at updated at and 10489 07:22:06,958 --> 07:22:09,240 name 10490 07:22:09,240 --> 07:22:12,240 values dollar sign 10491 07:22:12,240 --> 07:22:16,558 one dollar sign 2 dollar sign 3 dollar 10492 07:22:16,558 --> 07:22:19,680 sign 4 okay so what's this nonsense 10493 07:22:19,680 --> 07:22:25,120 right in sqlc each dollar sign number is 10494 07:22:25,120 --> 07:22:27,000 interpolated with the parameters for the 10495 07:22:27,000 --> 07:22:29,080 function so this statement will create a 10496 07:22:29,080 --> 07:22:31,000 new function called create user 10497 07:22:31,000 --> 07:22:33,878 with four parameters and the first 10498 07:22:33,878 --> 07:22:36,558 parameter will will go in right here the 10499 07:22:36,558 --> 07:22:38,478 second one the third one the fourth one 10500 07:22:38,478 --> 07:22:40,760 Etc so it allows us to create queries 10501 07:22:40,760 --> 07:22:43,398 that take arguments as input and then 10502 07:22:43,398 --> 07:22:46,520 we'll end the query with just return 10503 07:22:46,520 --> 07:22:48,318 returning 10504 07:22:48,318 --> 07:22:52,958 returning star okay we want to create a 10505 07:22:52,958 --> 07:22:55,478 new user and return that record right we 10506 07:22:55,478 --> 07:22:58,240 we expect one record back now let's use 10507 07:22:58,240 --> 07:23:01,080 sqlc to actually generate the go code 10508 07:23:01,080 --> 07:23:04,478 for this query we always run sqlc from 10509 07:23:04,478 --> 07:23:06,840 the root of our package rather than 10510 07:23:06,840 --> 07:23:09,680 within the query's directory itself um 10511 07:23:09,680 --> 07:23:10,840 and the reason that works is because we 10512 07:23:10,840 --> 07:23:13,680 have this sqlc do yaml file at the top 10513 07:23:13,680 --> 07:23:16,360 level okay so if everything was written 10514 07:23:16,360 --> 07:23:19,600 correctly we should be able to do sqlc 10515 07:23:19,600 --> 07:23:23,040 generate and what happens is it goes and 10516 07:23:23,040 --> 07:23:26,958 reads that query and it also reads our 10517 07:23:26,958 --> 07:23:28,000 table 10518 07:23:28,000 --> 07:23:31,638 definitions which we've specified here 10519 07:23:31,638 --> 07:23:35,200 right SQL schema so it knows the shape 10520 07:23:35,200 --> 07:23:38,040 of our tables and it knows the query we 10521 07:23:38,040 --> 07:23:39,520 want to create and it can go 10522 07:23:39,520 --> 07:23:41,718 automatically generate all of this go 10523 07:23:41,718 --> 07:23:45,280 code in the internal SL database package 10524 07:23:45,280 --> 07:23:47,478 now we need to actually use the database 10525 07:23:47,478 --> 07:23:50,280 in our go code so here in main.go I'm 10526 07:23:50,280 --> 07:23:53,798 going to create a new struct called API 10527 07:23:53,798 --> 07:23:55,478 config and it's going to hold a 10528 07:23:55,478 --> 07:23:58,958 connection to a database now this 10529 07:23:58,958 --> 07:24:01,040 database. queries type is actually 10530 07:24:01,040 --> 07:24:03,680 exposed by that code that we generated 10531 07:24:03,680 --> 07:24:05,360 using sqlc so you can poke around 10532 07:24:05,360 --> 07:24:06,878 through this package and kind of get 10533 07:24:06,878 --> 07:24:09,040 familiar with the generated code we 10534 07:24:09,040 --> 07:24:11,840 never manually update this code that's 10535 07:24:11,840 --> 07:24:14,200 generated by sqlc it's completely 10536 07:24:14,200 --> 07:24:16,000 managed by sqlc we're just going to 10537 07:24:16,000 --> 07:24:19,638 write raw SQL to generate this code okay 10538 07:24:19,638 --> 07:24:22,120 uh next thing we need to do is import 10539 07:24:22,120 --> 07:24:26,478 our database connection so here in EnV 10540 07:24:26,478 --> 07:24:31,160 we have our DB URL and we need to 10541 07:24:31,160 --> 07:24:33,520 grab that um and pull it into our 10542 07:24:33,520 --> 07:24:35,958 application we're also going to need to 10543 07:24:35,958 --> 07:24:39,240 disable SSL mode so SSL mode equals 10544 07:24:39,240 --> 07:24:41,398 disable um and it just this just tells 10545 07:24:41,398 --> 07:24:43,040 our code hey we don't need to be 10546 07:24:43,040 --> 07:24:46,440 connecting to our local database um 10547 07:24:46,440 --> 07:24:49,200 using encryption uh we kind of trust our 10548 07:24:49,200 --> 07:24:52,718 local database so we'll parse that as a 10549 07:24:52,718 --> 07:24:56,398 string so I'll do DB 10550 07:24:56,398 --> 07:25:00,878 URL and if the database URL is not found 10551 07:25:00,878 --> 07:25:01,638 then 10552 07:25:01,638 --> 07:25:04,840 we'll we'll report a message uh or we'll 10553 07:25:04,840 --> 07:25:07,878 log an error message and exit after that 10554 07:25:07,878 --> 07:25:08,718 we need to actually connect to the 10555 07:25:08,718 --> 07:25:10,600 database so the ghost standard library 10556 07:25:10,600 --> 07:25:13,798 has a built-in SQL package we can do SQL 10557 07:25:13,798 --> 07:25:16,478 doop the driver name that we'll be using 10558 07:25:16,478 --> 07:25:18,798 is just 10559 07:25:19,040 --> 07:25:21,360 postgress and then we can pass in the 10560 07:25:21,360 --> 07:25:23,798 connection string and this will return a 10561 07:25:23,798 --> 07:25:25,958 new connection and an 10562 07:25:25,958 --> 07:25:29,240 error and again if there's an 10563 07:25:29,240 --> 07:25:31,680 error we'll just go ahead and log a 10564 07:25:31,680 --> 07:25:34,160 message and 10565 07:25:36,478 --> 07:25:40,600 exit can't connect to 10566 07:25:40,600 --> 07:25:42,878 database now this is kind of a weird 10567 07:25:42,878 --> 07:25:44,718 quirky thing about how go handles 10568 07:25:44,718 --> 07:25:47,760 databases but we actually need to import 10569 07:25:47,760 --> 07:25:51,280 a database driver into our program um 10570 07:25:51,280 --> 07:25:52,440 but we don't actually need to call 10571 07:25:52,440 --> 07:25:54,638 anything from it so the sqlc docs 10572 07:25:54,638 --> 07:25:56,200 mention this but basically we just need 10573 07:25:56,200 --> 07:25:58,318 to include this line at the top of our 10574 07:25:58,318 --> 07:26:01,318 program and we do need to import it so 10575 07:26:01,318 --> 07:26:05,200 I'll do a goget um on that 10576 07:26:05,200 --> 07:26:07,680 libpq and we'll import it using that 10577 07:26:07,680 --> 07:26:10,120 underscore just to say include this code 10578 07:26:10,120 --> 07:26:12,200 in my program um even though I'm not 10579 07:26:12,200 --> 07:26:16,000 calling it directly okay with that there 10580 07:26:16,000 --> 07:26:17,718 uh now we should be able to create a new 10581 07:26:17,718 --> 07:26:19,558 API 10582 07:26:19,558 --> 07:26:24,360 config and let's just call it API 10583 07:26:24,760 --> 07:26:29,040 CFG and it takes as one of its Fields a 10584 07:26:29,040 --> 07:26:31,360 DB 10585 07:26:31,360 --> 07:26:35,478 where am I at I think I scrolled too 10586 07:26:36,240 --> 07:26:40,760 far BB oh and I should probably go mod 10587 07:26:40,760 --> 07:26:44,478 tidy and go mod 10588 07:26:44,478 --> 07:26:46,878 vendor so that I stop getting weird 10589 07:26:46,878 --> 07:26:50,280 errors in my in my vs 10590 07:26:50,280 --> 07:26:53,398 code okay uh this API CFG takes a 10591 07:26:53,398 --> 07:26:55,398 database. queries but if you look here 10592 07:26:55,398 --> 07:26:56,760 we don't have a database. queries we 10593 07:26:56,760 --> 07:26:58,638 have an SQL DB so we actually need to 10594 07:26:58,638 --> 07:27:02,080 convert it into a connection to our 10595 07:27:02,080 --> 07:27:06,040 package and we can do that with 10596 07:27:06,040 --> 07:27:09,600 database. new and we pass it as input 10597 07:27:09,600 --> 07:27:11,878 the connection and we'll get back 10598 07:27:11,878 --> 07:27:14,040 queries 10599 07:27:14,040 --> 07:27:19,360 eror here we can say if er do not equal 10600 07:27:27,240 --> 07:27:30,638 nil and pass in the queries 10601 07:27:30,638 --> 07:27:32,160 to the 10602 07:27:32,160 --> 07:27:34,520 struct no did I do that wrong maybe this 10603 07:27:34,520 --> 07:27:35,958 doesn't return an 10604 07:27:35,958 --> 07:27:38,000 error mismatch two variables but 10605 07:27:38,000 --> 07:27:39,600 database. new returns one okay cool so 10606 07:27:39,600 --> 07:27:41,040 this actually can't fail it's just a 10607 07:27:41,040 --> 07:27:42,958 it's just a simple 10608 07:27:42,958 --> 07:27:44,718 conversion we could actually even just 10609 07:27:44,718 --> 07:27:47,200 do this it's probably 10610 07:27:47,200 --> 07:27:50,840 easier great now we have an API config 10611 07:27:50,840 --> 07:27:53,080 that we can pass into our handlers so 10612 07:27:53,080 --> 07:27:56,360 that they have access to our database 10613 07:27:56,360 --> 07:27:58,680 let's write that create user Handler 10614 07:27:58,680 --> 07:27:59,840 okay so I'm just going to copy paste 10615 07:27:59,840 --> 07:28:02,000 this Handler Readiness and change it to 10616 07:28:02,000 --> 07:28:04,478 Handler 10617 07:28:04,478 --> 07:28:06,798 user and we'll update this to say 10618 07:28:06,798 --> 07:28:10,120 Handler this will be the create user 10619 07:28:10,120 --> 07:28:12,520 Handler now here's the interesting thing 10620 07:28:12,520 --> 07:28:15,398 about HTTP handlers in go the function 10621 07:28:15,398 --> 07:28:18,520 signature can't change but we do want to 10622 07:28:18,520 --> 07:28:22,160 pass into this function an additional 10623 07:28:22,160 --> 07:28:23,958 piece of data we want 10624 07:28:23,958 --> 07:28:28,000 to add this API config so the way we do 10625 07:28:28,000 --> 07:28:31,360 it is by making this function a method 10626 07:28:31,360 --> 07:28:33,280 so we do API 10627 07:28:33,280 --> 07:28:38,240 CFG is a pointer to an API config so our 10628 07:28:38,240 --> 07:28:40,240 function signature Remains the 10629 07:28:40,240 --> 07:28:42,398 Same right it still just accepts these 10630 07:28:42,398 --> 07:28:44,200 two parameters um but now we have some 10631 07:28:44,200 --> 07:28:46,318 additional data stored on the struct 10632 07:28:46,318 --> 07:28:49,440 itself uh that we can gain access to and 10633 07:28:49,440 --> 07:28:51,520 let's hook up this create user Handler 10634 07:28:51,520 --> 07:28:52,760 in 10635 07:28:52,760 --> 07:28:56,520 main so we'll add it to the V1 Handler 10636 07:28:56,520 --> 07:29:00,440 we'll do V1 router Dot 10637 07:29:00,440 --> 07:29:02,798 post we want this to be a post request 10638 07:29:02,798 --> 07:29:04,440 to/ 10639 07:29:04,440 --> 07:29:07,958 users and we want to use 10640 07:29:07,958 --> 07:29:12,558 the create Handler create user method 10641 07:29:12,558 --> 07:29:15,080 which we defined on this struct so we 10642 07:29:15,080 --> 07:29:19,760 can pass in API CFG do Handler create 10643 07:29:19,760 --> 07:29:22,160 user and now our Handler will have 10644 07:29:22,160 --> 07:29:26,600 access to um to the database okay 10645 07:29:26,600 --> 07:29:30,840 cool this Handler needs to take as input 10646 07:29:30,840 --> 07:29:33,200 a Json body it should 10647 07:29:33,200 --> 07:29:37,360 expect some parameters so we'll do type 10648 07:29:37,360 --> 07:29:40,558 parameters is instruct and I think for 10649 07:29:40,558 --> 07:29:43,000 now we just need a 10650 07:29:43,000 --> 07:29:46,000 name and we need to parse the request 10651 07:29:46,000 --> 07:29:49,398 body into this struct so we'll do json. 10652 07:29:49,398 --> 07:29:50,478 new 10653 07:29:50,478 --> 07:29:53,440 decoder and r. 10654 07:29:53,440 --> 07:29:56,000 body okay and this respond or this 10655 07:29:56,000 --> 07:29:59,680 returns a decoder 10656 07:30:01,000 --> 07:30:03,478 we do decoder do 10657 07:30:03,478 --> 07:30:07,000 decode and we want to decode into an 10658 07:30:07,000 --> 07:30:08,840 instance of the parameter struct so 10659 07:30:08,840 --> 07:30:12,600 we'll do prams is an empty parameter 10660 07:30:12,600 --> 07:30:15,798 struct and we'll decode 10661 07:30:15,798 --> 07:30:20,160 into a pointer to parameters and this 10662 07:30:20,160 --> 07:30:23,840 returns an error if anything goes 10663 07:30:25,240 --> 07:30:27,878 wrong if there is an error then we 10664 07:30:27,878 --> 07:30:30,040 should use that Handler function that we 10665 07:30:30,040 --> 07:30:32,600 made earlier respond with error and say 10666 07:30:32,600 --> 07:30:35,200 something like well we need to pass in W 10667 07:30:35,200 --> 07:30:36,398 um if something goes wrong here it's 10668 07:30:36,398 --> 07:30:38,000 probably a client side error right so 10669 07:30:38,000 --> 07:30:39,440 I'm just going to pass in a 10670 07:30:39,440 --> 07:30:41,638 400 and we'll 10671 07:30:41,638 --> 07:30:42,670 say 10672 07:30:42,670 --> 07:30:45,710 [Music] 10673 07:30:46,440 --> 07:30:52,318 um let's see error parsing 10674 07:30:55,200 --> 07:30:59,000 Json cool and then we'll return because 10675 07:30:59,000 --> 07:31:00,958 we're done at that that point if there 10676 07:31:00,958 --> 07:31:04,398 is an issue okay uh otherwise we have 10677 07:31:04,398 --> 07:31:07,120 access to a name so we can use our 10678 07:31:07,120 --> 07:31:10,360 database to create a user so we do API 10679 07:31:10,360 --> 07:31:12,478 CFG do 10680 07:31:12,478 --> 07:31:16,558 db. create user now this is the method 10681 07:31:16,558 --> 07:31:19,840 that sqlc generated for us right because 10682 07:31:19,840 --> 07:31:23,558 it it read our create user SQL and it 10683 07:31:23,558 --> 07:31:26,798 created a create user function for us 10684 07:31:26,798 --> 07:31:29,360 right and it created the parameters as a 10685 07:31:29,360 --> 07:31:31,040 struct so that's pretty 10686 07:31:31,040 --> 07:31:33,000 convenient uh let's see how this works 10687 07:31:33,000 --> 07:31:36,520 so create user accepts a context and 10688 07:31:36,520 --> 07:31:38,240 some create user pram so I'm going to 10689 07:31:38,240 --> 07:31:41,080 use uh I think 10690 07:31:41,080 --> 07:31:47,200 it's CTX no r. context there we go so 10691 07:31:47,200 --> 07:31:50,240 that's the context for this request and 10692 07:31:50,240 --> 07:31:52,878 then we pass in database. create user 10693 07:31:52,878 --> 07:31:55,520 prams this is struct and it should have 10694 07:31:55,520 --> 07:31:59,680 yep all of our uh types that we need to 10695 07:31:59,680 --> 07:32:02,398 pass pass into the create user function 10696 07:32:02,398 --> 07:32:05,520 okay so uh first things first an 10697 07:32:05,520 --> 07:32:08,040 ID the ID is a 10698 07:32:08,040 --> 07:32:11,240 uuid um and this is the first point at 10699 07:32:11,240 --> 07:32:12,478 which I think we've needed to use them 10700 07:32:12,478 --> 07:32:14,280 so we're going to have to import this 10701 07:32:14,280 --> 07:32:17,398 package so github.com gooogle uid this 10702 07:32:17,398 --> 07:32:21,600 is a very uh well-known uuid package in 10703 07:32:21,600 --> 07:32:25,718 go we will go get 10704 07:32:26,280 --> 07:32:28,558 it with that installed we should be able 10705 07:32:28,558 --> 07:32:31,398 to do you uu id. 10706 07:32:31,398 --> 07:32:34,160 new and that will just create a new 10707 07:32:34,160 --> 07:32:36,958 random uuid and if you weren't familiar 10708 07:32:36,958 --> 07:32:38,440 this is what a uu ID looks like in 10709 07:32:38,440 --> 07:32:41,318 string form it's basically just this 10710 07:32:41,318 --> 07:32:45,638 really long random uh bit of I mean in 10711 07:32:45,638 --> 07:32:47,478 this case represented as text that we 10712 07:32:47,478 --> 07:32:49,360 can use as a primary identifier for 10713 07:32:49,360 --> 07:32:51,000 every user so every user will get their 10714 07:32:51,000 --> 07:32:53,000 own random 10715 07:32:53,000 --> 07:32:57,760 ID cool um I should probably go mod tidy 10716 07:32:57,760 --> 07:32:59,958 go mod vendor 10717 07:32:59,958 --> 07:33:02,000 it's just good practice every time you 10718 07:33:02,000 --> 07:33:03,920 install a new package to make sure you 10719 07:33:03,920 --> 07:33:06,040 vendor it and go mod tidy kind of cleans 10720 07:33:06,040 --> 07:33:08,440 up any unused Imports um and resolve 10721 07:33:08,440 --> 07:33:09,520 some issues 10722 07:33:09,520 --> 07:33:12,440 there okay uh created at I'm going to 10723 07:33:12,440 --> 07:33:15,958 set to just time. now. 10724 07:33:15,958 --> 07:33:19,000 UTC created now and then updated at 10725 07:33:19,000 --> 07:33:20,398 should represent the last time it was 10726 07:33:20,398 --> 07:33:23,080 updated uh which would also be now right 10727 07:33:23,080 --> 07:33:25,440 because we're creating something new and 10728 07:33:25,440 --> 07:33:28,280 the user's name will just be pam. name 10729 07:33:28,280 --> 07:33:30,478 right it's whatever was passed in 10730 07:33:30,478 --> 07:33:33,520 to this HTTP request in the 10731 07:33:33,520 --> 07:33:36,160 body oh and I just am now realizing that 10732 07:33:36,160 --> 07:33:38,280 I messed up this Json tag should look 10733 07:33:38,280 --> 07:33:40,520 like 10734 07:33:41,440 --> 07:33:45,398 this okay cool um so create user should 10735 07:33:45,398 --> 07:33:47,798 probably return an error yep returns a 10736 07:33:47,798 --> 07:33:50,558 new user and an 10737 07:33:50,558 --> 07:33:52,558 error again if there was an error 10738 07:33:52,558 --> 07:33:54,760 creating the user we'll want to respond 10739 07:33:54,760 --> 07:33:56,000 with an 10740 07:33:56,000 --> 07:33:58,478 error and we'll 10741 07:33:58,478 --> 07:34:00,478 say good 10742 07:34:00,478 --> 07:34:03,318 create 10743 07:34:03,600 --> 07:34:07,638 user uh 400 seems fine and then we'll 10744 07:34:07,638 --> 07:34:11,000 actually respond with the user object 10745 07:34:11,000 --> 07:34:14,200 itself okay database. user and see how 10746 07:34:14,200 --> 07:34:15,680 that goes well let's let's actually take 10747 07:34:15,680 --> 07:34:17,600 a look and see what does a database. 10748 07:34:17,600 --> 07:34:20,360 user even look 10749 07:34:23,318 --> 07:34:25,240 like I'm 10750 07:34:25,240 --> 07:34:27,160 curious yeah so all these I mean all 10751 07:34:27,160 --> 07:34:28,958 these fields are exported so they should 10752 07:34:28,958 --> 07:34:30,878 Marshall to J on just fine let's go 10753 07:34:30,878 --> 07:34:33,280 ahead and run this and see and see what 10754 07:34:33,280 --> 07:34:34,878 we get before we run the code though it 10755 07:34:34,878 --> 07:34:35,878 looks like I've got a couple little 10756 07:34:35,878 --> 07:34:37,558 things to resolve here so errors is 10757 07:34:37,558 --> 07:34:40,878 already defined there and then here oh 10758 07:34:40,878 --> 07:34:42,680 I'm messing something up we need to pass 10759 07:34:42,680 --> 07:34:45,200 that in we need to interpolate that cool 10760 07:34:45,200 --> 07:34:47,398 oh and here as 10761 07:34:47,398 --> 07:34:50,680 well percent V because those are errors 10762 07:34:50,680 --> 07:34:53,360 okay cool um now let's go ahead and run 10763 07:34:53,360 --> 07:34:56,798 build and run the code so go build 10764 07:34:56,798 --> 07:35:00,798 and run RSS a 10765 07:35:00,798 --> 07:35:03,958 okay Ser server has started so let's go 10766 07:35:03,958 --> 07:35:06,280 ahead and open up the Thunder 10767 07:35:06,280 --> 07:35:09,760 client and now we'll be sending a post 10768 07:35:09,760 --> 07:35:12,760 request to the users's 10769 07:35:12,760 --> 07:35:17,760 endpoint and we'll be sending in a Json 10770 07:35:17,760 --> 07:35:23,600 body oh me grow this just a little 10771 07:35:23,680 --> 07:35:26,638 bit and we need to specify a name I'm 10772 07:35:26,638 --> 07:35:29,878 going to create a new user called Lane 10773 07:35:29,878 --> 07:35:32,638 and let's see what happens couldn't 10774 07:35:32,638 --> 07:35:36,798 create user database Wags Lane does not 10775 07:35:36,798 --> 07:35:39,280 exist it looks to me like I probably 10776 07:35:39,280 --> 07:35:41,280 messed up my connection string let's go 10777 07:35:41,280 --> 07:35:42,600 take a look at 10778 07:35:42,600 --> 07:35:45,718 that so here in 10779 07:35:45,718 --> 07:35:48,680 EnV yeah okay we forgot to or I forgot 10780 07:35:48,680 --> 07:35:51,440 to add um the name of the database here 10781 07:35:51,440 --> 07:35:55,160 at the end so uh we we need to do slash 10782 07:35:55,160 --> 07:35:57,000 name of database all right let's try 10783 07:35:57,000 --> 07:36:01,160 that again let's rebuild the server 10784 07:36:01,160 --> 07:36:04,160 and resend that request cool we got a 10785 07:36:04,160 --> 07:36:07,760 200 response it looks like that is a new 10786 07:36:07,760 --> 07:36:11,638 random ID great created at update at and 10787 07:36:11,638 --> 07:36:14,160 the name next just to make sure that the 10788 07:36:14,160 --> 07:36:15,760 record actually was created in the 10789 07:36:15,760 --> 07:36:17,718 database server itself I'm going to pop 10790 07:36:17,718 --> 07:36:22,680 back over here to PG admin um refresh my 10791 07:36:22,680 --> 07:36:24,878 tables there's our users table and rerun 10792 07:36:24,878 --> 07:36:27,798 this select star from users perfect 10793 07:36:27,798 --> 07:36:29,200 looks like we've got one record in here 10794 07:36:29,200 --> 07:36:31,360 with all of the data that I would expect 10795 07:36:31,360 --> 07:36:33,318 now I want to make one more optimization 10796 07:36:33,318 --> 07:36:35,280 to our code here you can see in this 10797 07:36:35,280 --> 07:36:38,120 Json response that the Fe the key names 10798 07:36:38,120 --> 07:36:40,878 in the Json object are the same as the 10799 07:36:40,878 --> 07:36:44,920 exported key names here in the user 10800 07:36:44,920 --> 07:36:47,080 struct in the database package now we 10801 07:36:47,080 --> 07:36:50,240 can't change this struct manually um 10802 07:36:50,240 --> 07:36:52,958 again this is generated by sqlc so what 10803 07:36:52,958 --> 07:36:56,240 I think we should do is instead create a 10804 07:36:56,240 --> 07:37:00,600 new models folder models. go 10805 07:37:00,600 --> 07:37:01,920 in the main 10806 07:37:01,920 --> 07:37:05,318 package and here we'll create our own 10807 07:37:05,318 --> 07:37:09,638 user type so type user struct and it 10808 07:37:09,638 --> 07:37:11,840 will be nearly identical so let me go 10809 07:37:11,840 --> 07:37:14,558 grab this one be nearly 10810 07:37:14,558 --> 07:37:16,520 identical the only difference at this 10811 07:37:16,520 --> 07:37:19,798 point is that I'm going to add Json 10812 07:37:19,798 --> 07:37:23,398 tags so that I can specify you know what 10813 07:37:23,398 --> 07:37:26,080 these names should be and we've been 10814 07:37:26,080 --> 07:37:28,478 using kind of this snake case convention 10815 07:37:28,478 --> 07:37:31,000 so I'm just going to stick with that so 10816 07:37:31,000 --> 07:37:35,000 updated at and name and I'm going to 10817 07:37:35,000 --> 07:37:37,920 create a function uh we'll say database 10818 07:37:37,920 --> 07:37:43,798 user to user and it will take a DB 10819 07:37:45,160 --> 07:37:49,360 user and return a user and all this does 10820 07:37:49,360 --> 07:37:53,280 is return a new user struct where uh 10821 07:37:53,280 --> 07:37:55,798 we've kind of populate it with all of 10822 07:37:55,798 --> 07:37:58,280 the all of the stuff from the database 10823 07:37:58,280 --> 07:38:01,120 user so again the purpose of this is 10824 07:38:01,120 --> 07:38:05,240 really just I want to own the shape um 10825 07:38:05,240 --> 07:38:07,240 that's being returned over the wire 10826 07:38:07,240 --> 07:38:10,240 right on our HTTP responses um and now I 10827 07:38:10,240 --> 07:38:11,878 have the power to configure that easily 10828 07:38:11,878 --> 07:38:13,760 within within my 10829 07:38:13,760 --> 07:38:16,160 application so we'll go ahead and just 10830 07:38:16,160 --> 07:38:20,080 uh paste these in 10831 07:38:22,600 --> 07:38:27,040 here okay and then in my user Handler 10832 07:38:27,040 --> 07:38:28,920 rather than responding with the database 10833 07:38:28,920 --> 07:38:32,398 user I'm going to respond with our 10834 07:38:32,398 --> 07:38:37,080 user cool let's rerun and build 10835 07:38:37,080 --> 07:38:40,680 that and let's run our query again now 10836 07:38:40,680 --> 07:38:43,040 remember we already have a user in our 10837 07:38:43,040 --> 07:38:45,680 database so I'm going 10838 07:38:45,680 --> 07:38:49,240 to create a second one uh let's call 10839 07:38:49,240 --> 07:38:51,520 this one 10840 07:38:51,718 --> 07:38:54,600 Rob and this time you can see we have 10841 07:38:54,600 --> 07:38:56,920 those snake case 10842 07:38:56,920 --> 07:39:00,760 keys and again I'm going to go check in 10843 07:39:00,760 --> 07:39:03,080 PG admin to make sure that Rob is there 10844 07:39:03,080 --> 07:39:05,398 perfect now we've got Lane and Rob and 10845 07:39:05,398 --> 07:39:06,958 you can see they have different randomly 10846 07:39:06,958 --> 07:39:09,120 generated IDs and their timestamps are 10847 07:39:09,120 --> 07:39:11,160 slightly different we're going to be 10848 07:39:11,160 --> 07:39:14,318 using API keys to authenticate our users 10849 07:39:14,318 --> 07:39:16,120 on This Server the nice thing about an 10850 07:39:16,120 --> 07:39:18,120 API key is Not only is a little more 10851 07:39:18,120 --> 07:39:20,360 secure than a username and a password 10852 07:39:20,360 --> 07:39:22,798 but because it's so long it also serves 10853 07:39:22,798 --> 07:39:25,638 as a unique ID for that user so we don't 10854 07:39:25,638 --> 07:39:27,478 even need a combo of username password 10855 07:39:27,478 --> 07:39:30,280 we can just use the API key in order to 10856 07:39:30,280 --> 07:39:33,120 kind of uniquely identify people so we 10857 07:39:33,120 --> 07:39:35,360 need to run a migration that adds a new 10858 07:39:35,360 --> 07:39:38,520 field to the user's table so that we can 10859 07:39:38,520 --> 07:39:40,680 store their API Keys now we've already 10860 07:39:40,680 --> 07:39:42,920 created this migration that creates the 10861 07:39:42,920 --> 07:39:44,478 users's table and we don't want to 10862 07:39:44,478 --> 07:39:46,558 modify this because it's generally a 10863 07:39:46,558 --> 07:39:48,958 really bad idea to go modifying your 10864 07:39:48,958 --> 07:39:50,718 existing migrations instead we create a 10865 07:39:50,718 --> 07:39:52,478 new one so I'm going to create a new one 10866 07:39:52,478 --> 07:39:54,558 and we'll call it 02 because we want it 10867 07:39:54,558 --> 07:39:57,798 to run after uh the first migration and 10868 07:39:57,798 --> 07:39:59,878 again Goose uses these numbers to know 10869 07:39:59,878 --> 07:40:02,200 in which order it should run uh the 10870 07:40:02,200 --> 07:40:07,000 migrations and we'll call it users API 10871 07:40:07,000 --> 07:40:10,440 key and the migration statements are 10872 07:40:10,440 --> 07:40:12,638 going to look a little bit different 10873 07:40:12,638 --> 07:40:14,680 okay so the up statement is going to be 10874 07:40:14,680 --> 07:40:18,638 an alter table so alter table users 10875 07:40:18,638 --> 07:40:20,318 We'll add a 10876 07:40:20,318 --> 07:40:22,718 column and we'll call the column just 10877 07:40:22,718 --> 07:40:26,280 API uncore key it's going to be a varar 10878 07:40:26,280 --> 07:40:27,160 so 10879 07:40:27,160 --> 07:40:29,638 varar 64 now the difference between 10880 07:40:29,638 --> 07:40:31,798 varar and text um at least for our 10881 07:40:31,798 --> 07:40:34,120 purposes here is that the varar is 10882 07:40:34,120 --> 07:40:36,478 exactly 64 characters long so we're 10883 07:40:36,478 --> 07:40:39,120 saying we want our API keys to be 64 10884 07:40:39,120 --> 07:40:42,080 characters long and we want those API 10885 07:40:42,080 --> 07:40:44,398 keys to be unique no two users should 10886 07:40:44,398 --> 07:40:47,000 have the same API key um we also don't 10887 07:40:47,000 --> 07:40:49,160 want them to be null and we're going to 10888 07:40:49,160 --> 07:40:50,600 set a 10889 07:40:50,600 --> 07:40:53,718 default a default API key and this is 10890 07:40:53,718 --> 07:40:55,398 important because if we didn't set a 10891 07:40:55,398 --> 07:40:57,760 default we'd run into an issue when we 10892 07:40:57,760 --> 07:41:00,120 run this migration remember we already 10893 07:41:00,120 --> 07:41:03,440 have two users in our database currently 10894 07:41:03,440 --> 07:41:06,160 so if we just try to add a column that 10895 07:41:06,160 --> 07:41:09,318 has these unique not null constraints on 10896 07:41:09,318 --> 07:41:12,200 it then what's the SQL database going to 10897 07:41:12,200 --> 07:41:15,000 do how is it going to generate new API 10898 07:41:15,000 --> 07:41:17,240 keys that are unique and not null 10899 07:41:17,240 --> 07:41:19,798 typically it would just default the new 10900 07:41:19,798 --> 07:41:21,440 um you you know the field in the 10901 07:41:21,440 --> 07:41:23,600 existing records to null but because 10902 07:41:23,600 --> 07:41:25,760 we've said they can't be null and they 10903 07:41:25,760 --> 07:41:28,920 must be unique we need to provide a 10904 07:41:28,920 --> 07:41:31,120 unique unique default for every new 10905 07:41:31,120 --> 07:41:33,240 record or for excuse me for every 10906 07:41:33,240 --> 07:41:36,520 existing record in the database so the 10907 07:41:36,520 --> 07:41:38,718 default value that we need to add again 10908 07:41:38,718 --> 07:41:41,200 needs to be unique for every person so 10909 07:41:41,200 --> 07:41:43,240 we're actually going to have to use some 10910 07:41:43,240 --> 07:41:45,478 random number generation so that we can 10911 07:41:45,478 --> 07:41:48,240 generate a unique API key for every user 10912 07:41:48,240 --> 07:41:50,000 and this is the snippet of code that 10913 07:41:50,000 --> 07:41:53,360 does that again you can go grab this in 10914 07:41:53,360 --> 07:41:55,958 the text instructions for this project 10915 07:41:55,958 --> 07:41:57,600 over on bootd but let me explain 10916 07:41:57,600 --> 07:41:58,718 basically what it's doing we're 10917 07:41:58,718 --> 07:41:59,680 generating 10918 07:41:59,680 --> 07:42:01,958 some random byes and then we're casting 10919 07:42:01,958 --> 07:42:05,200 it into a bite array and we're using the 10920 07:42:05,200 --> 07:42:10,200 shaw 256 hash function to get kind of a 10921 07:42:10,200 --> 07:42:13,280 a fixed size output so we're saying take 10922 07:42:13,280 --> 07:42:17,958 a a big random slice of bytes hash them 10923 07:42:17,958 --> 07:42:20,160 with straw 256 so that we get a fixed 10924 07:42:20,160 --> 07:42:24,120 size output and then encode it in 10925 07:42:24,120 --> 07:42:27,080 hexadecimal and that's so that we get 64 10926 07:42:27,080 --> 07:42:29,440 unique heximal characters this makes 10927 07:42:29,440 --> 07:42:30,680 more sense when we actually run the 10928 07:42:30,680 --> 07:42:32,840 query and you see what the output looks 10929 07:42:32,840 --> 07:42:35,040 like and then as far as the down 10930 07:42:35,040 --> 07:42:37,440 migration goes we just need to alter 10931 07:42:37,440 --> 07:42:40,280 table users and 10932 07:42:40,280 --> 07:42:45,000 drop column API key again down 10933 07:42:45,000 --> 07:42:47,840 migrations should just undo whatever was 10934 07:42:47,840 --> 07:42:49,958 done in the up migration let's go ahead 10935 07:42:49,958 --> 07:42:51,318 and run this migration so I'm going to 10936 07:42:51,318 --> 07:42:53,760 need to change directory into 10937 07:42:53,760 --> 07:42:55,600 SQL uh 10938 07:42:55,600 --> 07:42:59,718 schema then we'll run goose postgress 10939 07:42:59,718 --> 07:43:01,120 then let me go grab the connection 10940 07:43:01,120 --> 07:43:04,080 string now we do need to peel off this 10941 07:43:04,080 --> 07:43:06,760 SSL mode disable Goose doesn't need that 10942 07:43:06,760 --> 07:43:08,318 um just our code needs that so I'm going 10943 07:43:08,318 --> 07:43:10,840 to grab the rest of the string and we'll 10944 07:43:10,840 --> 07:43:12,280 run an up 10945 07:43:12,280 --> 07:43:14,878 migration cool so it looks like it ran 10946 07:43:14,878 --> 07:43:16,798 successfully let's go see if those 10947 07:43:16,798 --> 07:43:20,398 default values look good run the select 10948 07:43:20,398 --> 07:43:24,040 star statement and there you can see the 10949 07:43:24,040 --> 07:43:25,280 new 10950 07:43:25,280 --> 07:43:28,558 AES so big old heximal strings that 10951 07:43:28,558 --> 07:43:31,080 uniquely identify every user and should 10952 07:43:31,080 --> 07:43:33,478 be kept secret by the user because just 10953 07:43:33,478 --> 07:43:35,878 the API key is enough to authenticate 10954 07:43:35,878 --> 07:43:38,160 the user now that we've got our 10955 07:43:38,160 --> 07:43:40,520 migration and we've updated our schema 10956 07:43:40,520 --> 07:43:43,040 we actually need to go update our query 10957 07:43:43,040 --> 07:43:45,920 right we need to be creating new API 10958 07:43:45,920 --> 07:43:50,000 keys for new users so let's go update 10959 07:43:50,000 --> 07:43:51,878 our create user function it should now 10960 07:43:51,878 --> 07:43:55,920 accept an API key as the last 10961 07:43:55,920 --> 07:44:00,478 parameter and pass it in here 10962 07:44:00,478 --> 07:44:01,760 actually you know 10963 07:44:01,760 --> 07:44:04,398 what if we do it this way we're 10964 07:44:04,398 --> 07:44:06,120 basically telling our application code 10965 07:44:06,120 --> 07:44:08,840 hey you need to go generate an API key 10966 07:44:08,840 --> 07:44:11,240 in the same way that we generated it 10967 07:44:11,240 --> 07:44:13,080 here in our SQL I think it would 10968 07:44:13,080 --> 07:44:15,600 actually be easier what if we just take 10969 07:44:15,600 --> 07:44:18,520 this and plop 10970 07:44:18,520 --> 07:44:20,718 that in 10971 07:44:20,718 --> 07:44:23,160 here right so now we'll use we'll use 10972 07:44:23,160 --> 07:44:25,318 SQL to generate the new API Keys we 10973 07:44:25,318 --> 07:44:26,718 don't even need to update the function 10974 07:44:26,718 --> 07:44:29,120 signature of our create user function 10975 07:44:29,120 --> 07:44:31,080 cool so the SQL will just handle the 10976 07:44:31,080 --> 07:44:33,280 creation of new API Keys every time a 10977 07:44:33,280 --> 07:44:36,280 new user is created all right now we 10978 07:44:36,280 --> 07:44:37,600 should be able to 10979 07:44:37,600 --> 07:44:41,000 run sqlc 10980 07:44:41,000 --> 07:44:43,200 generate insert has more Expressions 10981 07:44:43,200 --> 07:44:45,360 than Target columns let's 10982 07:44:45,360 --> 07:44:48,240 see oh right sorry we we do still need 10983 07:44:48,240 --> 07:44:50,840 to pass in the API key as the column 10984 07:44:50,840 --> 07:44:53,120 name um the difference is because we're 10985 07:44:53,120 --> 07:44:55,638 not using dollar sign 5 our function 10986 07:44:55,638 --> 07:44:57,360 signature won't change this got a little 10987 07:44:57,360 --> 07:44:58,638 confusing I was reading it like a 10988 07:44:58,638 --> 07:45:00,478 function signature even though it is it 10989 07:45:00,478 --> 07:45:04,558 is SQL okay run that again it went off 10990 07:45:04,558 --> 07:45:06,160 without a hitch you can see it updated a 10991 07:45:06,160 --> 07:45:08,200 few files in our database package now we 10992 07:45:08,200 --> 07:45:10,958 should be able to go use that in our 10993 07:45:10,958 --> 07:45:13,840 code but before we test our server let's 10994 07:45:13,840 --> 07:45:16,120 add one more thing let's give us a way 10995 07:45:16,120 --> 07:45:18,798 to get a user so we'll create a new 10996 07:45:18,798 --> 07:45:23,280 function and this one we'll call get 10997 07:45:23,280 --> 07:45:27,798 user by API key it should return a 10998 07:45:27,798 --> 07:45:29,600 single row 10999 07:45:29,600 --> 07:45:30,798 and it's going to be a select statement 11000 07:45:30,798 --> 07:45:33,638 so select star 11001 07:45:33,638 --> 07:45:35,638 from 11002 07:45:35,638 --> 07:45:37,478 users 11003 07:45:37,478 --> 07:45:42,840 where API key equals dollar sign 11004 07:45:42,840 --> 07:45:46,600 one and we'll run sqlc generate again to 11005 07:45:46,600 --> 07:45:49,160 generate the code for that query you can 11006 07:45:49,160 --> 07:45:53,080 see it created it here so in our Handler 11007 07:45:53,080 --> 07:45:55,718 user function we actually don't need to 11008 07:45:55,718 --> 07:45:58,280 make any changes to our create user 11009 07:45:58,280 --> 07:46:00,080 Handler right right we didn't change the 11010 07:46:00,080 --> 07:46:01,318 number of parameters that we need to 11011 07:46:01,318 --> 07:46:03,638 pass in for the API key it's handled 11012 07:46:03,638 --> 07:46:06,718 kind of under the hood by the SQL query 11013 07:46:06,718 --> 07:46:09,080 but we do need a new Handler for getting 11014 07:46:09,080 --> 07:46:12,680 users so let's go ahead and add 11015 07:46:12,878 --> 07:46:16,680 that so I'm going to copy paste that do 11016 07:46:16,680 --> 07:46:21,080 Handler get user by API 11017 07:46:21,080 --> 07:46:22,958 key maybe we can just let's just 11018 07:46:22,958 --> 07:46:24,558 simplify this let's just call it Handler 11019 07:46:24,558 --> 07:46:25,398 get 11020 07:46:25,398 --> 07:46:27,680 user now this Handler is going to look 11021 07:46:27,680 --> 07:46:30,840 very different 11022 07:46:31,240 --> 07:46:34,040 this is an authenticated endpoint so in 11023 07:46:34,040 --> 07:46:36,478 order to create a user on our API 11024 07:46:36,478 --> 07:46:38,240 basically to register a new account you 11025 07:46:38,240 --> 07:46:40,478 don't need to have an API key but if you 11026 07:46:40,478 --> 07:46:43,040 want to get your own user information 11027 07:46:43,040 --> 07:46:46,398 you have to give us an API key first 11028 07:46:46,398 --> 07:46:48,200 this isn't going to be the only 11029 07:46:48,200 --> 07:46:50,398 authenticated endpoint or the endpoint 11030 07:46:50,398 --> 07:46:52,760 that you can only do if you're logged in 11031 07:46:52,760 --> 07:46:55,600 um so I think it makes sense to kind of 11032 07:46:55,600 --> 07:46:58,558 abstract the logic for getting a user by 11033 07:46:58,558 --> 07:47:02,478 their API key into a package so under 11034 07:47:02,478 --> 07:47:04,200 the internal package here where we have 11035 07:47:04,200 --> 07:47:05,878 our database code I'm going to create a 11036 07:47:05,878 --> 07:47:08,240 new package and we'll just call it 11037 07:47:08,240 --> 07:47:10,840 o and in there I'll create a new file 11038 07:47:10,840 --> 07:47:13,360 we'll call it o.o and this whole package 11039 07:47:13,360 --> 07:47:17,398 will just be called 11040 07:47:17,520 --> 07:47:22,080 off now the only function that we care 11041 07:47:22,080 --> 07:47:24,520 to export in this off package is going 11042 07:47:24,520 --> 07:47:27,478 to be this one called get API key and 11043 07:47:27,478 --> 07:47:29,558 its purpose get API key key will'll say 11044 07:47:29,558 --> 07:47:30,440 it 11045 07:47:30,440 --> 07:47:36,878 extracts an API key from the headers of 11046 07:47:36,878 --> 07:47:39,638 an HTTP request so it's going to go into 11047 07:47:39,638 --> 07:47:41,240 the headers look for a specific header 11048 07:47:41,240 --> 07:47:43,920 and see if it can find the API key if it 11049 07:47:43,920 --> 07:47:46,040 can it'll return it otherwise it will 11050 07:47:46,040 --> 07:47:47,440 return an 11051 07:47:47,440 --> 07:47:50,638 error now as the authors of This Server 11052 07:47:50,638 --> 07:47:52,600 we get to decide what we want the 11053 07:47:52,600 --> 07:47:54,120 authentication header to look like so 11054 07:47:54,120 --> 07:47:55,318 I'm just going to 11055 07:47:55,318 --> 07:47:59,160 say um example 11056 07:47:59,160 --> 07:48:01,680 let's expect an authorization header so 11057 07:48:01,680 --> 07:48:03,638 the key of the header will be 11058 07:48:03,638 --> 07:48:07,280 authorization and the value will be API 11059 07:48:07,280 --> 07:48:11,958 key and then some you know like insert 11060 07:48:11,958 --> 07:48:17,718 API key here okay so we're looking for a 11061 07:48:17,718 --> 07:48:19,520 header of this 11062 07:48:19,520 --> 07:48:22,160 format so first let's look and see if we 11063 07:48:22,160 --> 07:48:23,798 can find a value associated with the 11064 07:48:23,798 --> 07:48:26,718 authorization key um we're just using 11065 07:48:26,718 --> 07:48:28,558 the HTTP standard Library here so we can 11066 07:48:28,558 --> 07:48:31,718 do headers do 11067 07:48:31,718 --> 07:48:34,878 getet authorization and this should 11068 07:48:34,878 --> 07:48:37,120 return let's see a string okay so the 11069 07:48:37,120 --> 07:48:40,878 value associated with this with this 11070 07:48:40,878 --> 07:48:44,878 header key now if value is the empty 11071 07:48:44,878 --> 07:48:49,360 string then we can just say uh turn 11072 07:48:49,360 --> 07:48:53,080 empty string and an error say errors. 11073 07:48:53,080 --> 07:48:57,718 new no authentication 11074 07:48:57,718 --> 07:49:02,798 info found so otherwise we have a valid 11075 07:49:02,798 --> 07:49:06,040 value so we could do something like this 11076 07:49:06,040 --> 07:49:07,600 uh 11077 07:49:07,600 --> 07:49:11,080 vows strings. 11078 07:49:11,080 --> 07:49:13,040 split 11079 07:49:13,040 --> 07:49:17,558 vow okay so strings. split takes a 11080 07:49:17,558 --> 07:49:20,280 string as input and a delimiter so we're 11081 07:49:20,280 --> 07:49:22,680 going to say we want to split this 11082 07:49:22,680 --> 07:49:25,478 string here right the the value given to 11083 07:49:25,478 --> 07:49:27,920 us uh by the auth authorization header 11084 07:49:27,920 --> 07:49:31,680 uh we want to split on Spaces okay so 11085 07:49:31,680 --> 07:49:34,478 next we can say if the length of 11086 07:49:34,478 --> 07:49:37,000 vals does not equal 11087 07:49:37,000 --> 07:49:40,120 two then again we can return an error 11088 07:49:40,120 --> 07:49:43,120 saying like you know maybe 11089 07:49:43,120 --> 07:49:46,798 malformed malformed a header right 11090 07:49:46,798 --> 07:49:50,478 because we're expecting that the value 11091 07:49:50,478 --> 07:49:54,280 of this key is two like two specific 11092 07:49:54,280 --> 07:49:56,840 values separated by a space the first 11093 07:49:56,840 --> 07:49:59,478 should be API key and the second should 11094 07:49:59,478 --> 07:50:02,398 be the API key right the first should 11095 07:50:02,398 --> 07:50:04,398 just be the string API key and the 11096 07:50:04,398 --> 07:50:06,440 second should be the actual API 11097 07:50:06,440 --> 07:50:10,360 key okay so if the length is wrong then 11098 07:50:10,360 --> 07:50:11,840 uh next we should probably check and 11099 07:50:11,840 --> 07:50:13,558 make sure they typed this in correctly 11100 07:50:13,558 --> 07:50:17,840 so we can say uh if vals at zero does 11101 07:50:17,840 --> 07:50:21,318 not equal API 11102 07:50:21,680 --> 07:50:24,718 key malformed offhe 11103 07:50:24,718 --> 07:50:28,080 header we could say malformed first part 11104 07:50:28,080 --> 07:50:32,840 of offhe header okay 11105 07:50:32,840 --> 07:50:36,318 otherwise we can just 11106 07:50:36,318 --> 07:50:41,040 return B at one and no error 11107 07:50:41,040 --> 07:50:45,558 right because by that point we sure that 11108 07:50:45,558 --> 07:50:47,760 all all this part was correct and we're 11109 07:50:47,760 --> 07:50:49,680 extracting just the API 11110 07:50:49,680 --> 07:50:52,160 key okay what did I screw up here 11111 07:50:52,160 --> 07:50:53,920 errors. new oh right you're not supposed 11112 07:50:53,920 --> 07:50:57,440 to capitalize errors in go that is a a 11113 07:50:57,440 --> 07:51:00,558 linting error 11114 07:51:01,080 --> 07:51:03,680 a stylistic error Okay 11115 07:51:03,680 --> 07:51:06,920 cool so now we've got the get API key 11116 07:51:06,920 --> 07:51:09,558 function we can go ahead and use this in 11117 07:51:09,558 --> 07:51:12,478 our get user Handler so let's go ahead 11118 07:51:12,478 --> 07:51:15,760 and grab that API key so API key and 11119 07:51:15,760 --> 07:51:20,240 error o. getet API key and we pass in 11120 07:51:20,240 --> 07:51:23,120 the HTTP headers so r. 11121 07:51:23,120 --> 07:51:26,840 header perfect if there is an error 11122 07:51:26,840 --> 07:51:29,558 let's handle it 11123 07:51:29,558 --> 07:51:32,840 we can just respond with an error 11124 07:51:32,840 --> 07:51:35,318 saying off 11125 07:51:35,318 --> 07:51:38,520 error and 400 we should probably do like 11126 07:51:38,520 --> 07:51:40,958 a 403 and in fact now that I'm thinking 11127 07:51:40,958 --> 07:51:43,798 about HTTP codes creating a user 11128 07:51:43,798 --> 07:51:45,878 probably should be a 2011 instead of a 11129 07:51:45,878 --> 07:51:49,160 200 like you probably won't run into any 11130 07:51:49,160 --> 07:51:52,878 issues for using a 200 um but 201 is the 11131 07:51:52,878 --> 07:51:55,558 created code so it's like a little more 11132 07:51:55,558 --> 07:51:57,798 correct uh if you're looking at it from 11133 07:51:57,798 --> 07:52:00,160 kind of a rest full HTTP standpoint and 11134 07:52:00,160 --> 07:52:02,638 then 403 um is one of these kind of 11135 07:52:02,638 --> 07:52:05,000 permissions errors so that should be 11136 07:52:05,000 --> 07:52:08,440 good okay now that we have an API key we 11137 07:52:08,440 --> 07:52:11,920 can use our database query that we 11138 07:52:11,920 --> 07:52:15,558 created. get user by API key again we'll 11139 07:52:15,558 --> 07:52:19,760 pass in the requests context and the API 11140 07:52:19,760 --> 07:52:22,760 key I haven't really touched on this 11141 07:52:22,760 --> 07:52:26,200 yet in go um there is a context package 11142 07:52:26,200 --> 07:52:28,558 in the standard library and basically it 11143 07:52:28,558 --> 07:52:30,080 gives you a way to 11144 07:52:30,080 --> 07:52:32,680 track something that's happening across 11145 07:52:32,680 --> 07:52:35,558 multiple go routines and the most 11146 07:52:35,558 --> 07:52:36,760 important thing that you can do with the 11147 07:52:36,760 --> 07:52:40,080 context is you can cancel it so uh by 11148 07:52:40,080 --> 07:52:41,398 cancelling the context it would 11149 07:52:41,398 --> 07:52:44,080 effectively kill the HTTP request I 11150 07:52:44,080 --> 07:52:46,878 don't want to go too much into detail on 11151 07:52:46,878 --> 07:52:48,840 how all of that works here um you could 11152 07:52:48,840 --> 07:52:50,920 definitely go read up on it um but for 11153 07:52:50,920 --> 07:52:52,318 now just make sure that it's important 11154 07:52:52,318 --> 07:52:54,878 to kind of use the current context so 11155 07:52:54,878 --> 07:52:58,200 every HTTP do request has a context on 11156 07:52:58,200 --> 07:53:01,520 it and you should use that context um in 11157 07:53:01,520 --> 07:53:03,798 any calls you make within the Handler 11158 07:53:03,798 --> 07:53:06,878 that requires a context just in case uh 11159 07:53:06,878 --> 07:53:10,000 kind of cancellations happen Okay cool 11160 07:53:10,000 --> 07:53:14,798 uh that returns a user and an 11161 07:53:14,798 --> 07:53:18,798 error again if there is an 11162 07:53:18,958 --> 07:53:22,798 error Let's do let's use a better 11163 07:53:22,798 --> 07:53:26,558 uh string here 11164 07:53:27,440 --> 07:53:30,760 maybe couldn't get 11165 07:53:30,760 --> 07:53:33,600 user and this one let's just go with a 11166 07:53:33,600 --> 07:53:36,120 404 or a 400 for 11167 07:53:36,120 --> 07:53:41,398 now cool um and then we can respond with 11168 07:53:41,398 --> 07:53:43,958 Json this time it will just be a 200 11169 07:53:43,958 --> 07:53:46,798 code and again we should cast that 11170 07:53:46,798 --> 07:53:50,200 database user to the user uh model that 11171 07:53:50,200 --> 07:53:53,958 we defined here right with the the 11172 07:53:53,958 --> 07:53:56,680 nicely formatted Json tags and that 11173 07:53:56,680 --> 07:53:59,200 should be good okay let's hook up our 11174 07:53:59,200 --> 07:54:01,120 get user 11175 07:54:01,120 --> 07:54:03,760 Handler to our 11176 07:54:03,760 --> 07:54:09,318 router so here we'll do V1 router. getet 11177 07:54:09,318 --> 07:54:11,798 so same path SL 11178 07:54:11,798 --> 07:54:15,318 users but we'll be hooking up the get 11179 07:54:15,318 --> 07:54:18,760 user Handler to the get HTTP method so 11180 07:54:18,760 --> 07:54:21,160 again same path different method all 11181 07:54:21,160 --> 07:54:23,798 right let's test our new 11182 07:54:23,798 --> 07:54:26,240 endpoint um first I'm going to go ahead 11183 07:54:26,240 --> 07:54:28,478 and rerun sqlc generate cuz I can't 11184 07:54:28,478 --> 07:54:30,958 remember if I've done that and then 11185 07:54:30,958 --> 07:54:33,920 we'll build and run the 11186 07:54:35,600 --> 07:54:38,558 server okay with that running let's head 11187 07:54:38,558 --> 07:54:41,040 over to thunder 11188 07:54:41,040 --> 07:54:44,360 client and first let's create another 11189 07:54:44,360 --> 07:54:45,240 new 11190 07:54:45,240 --> 07:54:49,798 user so Json body me minimize this a 11191 07:54:49,798 --> 07:54:51,040 little 11192 07:54:51,040 --> 07:54:53,280 bit um let's keep create a new user 11193 07:54:53,280 --> 07:54:54,920 we'll call him 11194 07:54:54,920 --> 07:54:57,718 Rand and it'll be a post request that 11195 07:54:57,718 --> 07:55:00,040 looks good 11196 07:55:00,040 --> 07:55:03,398 okay response came back Rand was created 11197 07:55:03,398 --> 07:55:06,638 and this is rand's ID ah we screwed 11198 07:55:06,638 --> 07:55:08,840 something up we are not responding with 11199 07:55:08,840 --> 07:55:12,718 the API key let's go update 11200 07:55:12,718 --> 07:55:16,718 that so here in our model I believe it's 11201 07:55:16,718 --> 07:55:21,000 because we're not casting so we need API 11202 07:55:21,000 --> 07:55:22,638 E 11203 07:55:22,638 --> 07:55:24,318 string 11204 07:55:24,318 --> 07:55:26,958 bason API 11205 07:55:26,958 --> 07:55:29,798 key and then 11206 07:55:29,798 --> 07:55:32,200 here need to do that conversion so this 11207 07:55:32,200 --> 07:55:33,760 just getting dropped because we weren't 11208 07:55:33,760 --> 07:55:36,318 we weren't setting the API key 11209 07:55:36,318 --> 07:55:40,638 anywhere okay uh let's 11210 07:55:42,798 --> 07:55:45,318 rebuild and we'll create a new user 11211 07:55:45,318 --> 07:55:47,120 let's call this one 11212 07:55:47,120 --> 07:55:51,840 Joe Okay cool so Joe was created and it 11213 07:55:51,840 --> 07:55:54,478 actually returned the API key perfect 11214 07:55:54,478 --> 07:55:57,200 now let's go ahead and I'm going to 11215 07:55:57,200 --> 07:56:00,240 create a new request 11216 07:56:00,478 --> 07:56:05,360 this one also to Local Host 11217 07:56:05,360 --> 07:56:09,280 8080 slv1 users but this one will be a 11218 07:56:09,280 --> 07:56:12,240 get and we're going to add some headers 11219 07:56:12,240 --> 07:56:13,878 or specifically one header right we're 11220 07:56:13,878 --> 07:56:16,840 going to add our authorization header 11221 07:56:16,840 --> 07:56:19,760 and its value will be API 11222 07:56:19,760 --> 07:56:22,958 key and then the actual API key just 11223 07:56:22,958 --> 07:56:24,080 paste it in 11224 07:56:24,080 --> 07:56:27,878 there okay let's go ahead and run that 11225 07:56:27,878 --> 07:56:31,638 and it it's returning Joe it's good to 11226 07:56:31,638 --> 07:56:33,840 test failure cases too so let's just see 11227 07:56:33,840 --> 07:56:35,600 what happens if 11228 07:56:35,600 --> 07:56:38,638 we update this header and let's just 11229 07:56:38,638 --> 07:56:41,160 like let's just make something broken 11230 07:56:41,160 --> 07:56:42,920 let's just remove a section of the API 11231 07:56:42,920 --> 07:56:44,318 key and see what 11232 07:56:44,318 --> 07:56:46,760 happens cool we get a 400 batter request 11233 07:56:46,760 --> 07:56:48,958 couldn't get user SQL no rows in the 11234 07:56:48,958 --> 07:56:51,000 result set so essentially user is not 11235 07:56:51,000 --> 07:56:54,080 found perfect so we've got our users set 11236 07:56:54,080 --> 07:56:55,840 up and our authentication system now 11237 07:56:55,840 --> 07:56:57,080 it's time to actually get to some 11238 07:56:57,080 --> 07:56:59,040 business logic right this this is an RSS 11239 07:56:59,040 --> 07:57:01,280 feed aggregator so we need a way to 11240 07:57:01,280 --> 07:57:04,798 store feeds let's create a new schema or 11241 07:57:04,798 --> 07:57:06,798 rather a new migration in our schema 11242 07:57:06,798 --> 07:57:10,200 folder this will be O3 we'll call it 11243 07:57:10,200 --> 07:57:14,160 feed feeds dsql now this is going to be 11244 07:57:14,160 --> 07:57:16,080 a create table migration right we want 11245 07:57:16,080 --> 07:57:20,000 to create a feeds table so we'll do 11246 07:57:20,000 --> 07:57:21,558 create table 11247 07:57:21,558 --> 07:57:24,920 feeds now a feed and the drop will also 11248 07:57:24,920 --> 07:57:27,638 drop the feeds table a feed has an ID 11249 07:57:27,638 --> 07:57:29,398 just like a user um it also has a 11250 07:57:29,398 --> 07:57:31,798 created at and an updated at and it also 11251 07:57:31,798 --> 07:57:33,958 has a name like all of that is actually 11252 07:57:33,958 --> 07:57:36,160 very similar um what's unique about a 11253 07:57:36,160 --> 07:57:38,040 feed is it has a 11254 07:57:38,040 --> 07:57:42,398 URL uh which is text as well that is 11255 07:57:42,398 --> 07:57:45,000 unique and not 11256 07:57:45,000 --> 07:57:50,360 null and it also has a user 11257 07:57:50,360 --> 07:57:52,318 ID which 11258 07:57:52,318 --> 07:57:55,718 references sorry it's a user ID is a uu 11259 07:57:55,718 --> 07:57:59,040 ID which references 11260 07:57:59,040 --> 07:58:03,280 users ID and we'll also add the on 11261 07:58:03,280 --> 07:58:04,660 delete 11262 07:58:04,660 --> 07:58:06,160 [Music] 11263 07:58:06,160 --> 07:58:08,440 Cascade essentially what this does is it 11264 07:58:08,440 --> 07:58:11,160 says we have a user ID stored in our 11265 07:58:11,160 --> 07:58:13,240 feeds table that 11266 07:58:13,240 --> 07:58:16,280 references the ID of a user in the user 11267 07:58:16,280 --> 07:58:17,680 table right so this is this is 11268 07:58:17,680 --> 07:58:19,318 relational data this is a relational 11269 07:58:19,318 --> 07:58:22,000 database um essentially what this means 11270 07:58:22,000 --> 07:58:25,398 is if we try to create a feed for a user 11271 07:58:25,398 --> 07:58:27,440 ID that does not exist in the users 11272 07:58:27,440 --> 07:58:29,680 table we'll get an error uh which is 11273 07:58:29,680 --> 07:58:31,200 what we want because we don't want feeds 11274 07:58:31,200 --> 07:58:33,280 to be able to exist without a user who 11275 07:58:33,280 --> 07:58:35,680 created them and then this on delete 11276 07:58:35,680 --> 07:58:38,798 Cascade bit just says when a user is 11277 07:58:38,798 --> 07:58:41,638 deleted I want all of the feeds 11278 07:58:41,638 --> 07:58:43,798 associated with that user to be deleted 11279 07:58:43,798 --> 07:58:46,000 automatically it will Cascade and delete 11280 07:58:46,000 --> 07:58:48,200 all of them and let's run this migration 11281 07:58:48,200 --> 07:58:52,120 so I'm going to hop into the SQL schema 11282 07:58:52,120 --> 07:58:55,080 directory and from here we can run goose 11283 07:58:55,080 --> 07:58:58,360 postgress postgress and Gra my 11284 07:58:58,360 --> 07:59:00,000 connection screen again we don't need 11285 07:59:00,000 --> 07:59:03,440 the SSL mode stuff for goose grab the 11286 07:59:03,440 --> 07:59:08,638 rest of it and up cool now over here in 11287 07:59:08,638 --> 07:59:11,398 PG admin I can do a select star from 11288 07:59:11,398 --> 07:59:13,638 feeds and make sure that that table 11289 07:59:13,638 --> 07:59:16,398 exists with those fields next we'll need 11290 07:59:16,398 --> 07:59:18,520 a query to create a new feed so I'm 11291 07:59:18,520 --> 07:59:20,318 going to go ahead and copy this queries 11292 07:59:20,318 --> 07:59:23,360 file update it to feeds then we'll 11293 07:59:23,360 --> 07:59:24,958 delete this one because we don't need it 11294 07:59:24,958 --> 07:59:29,080 and we'll create a create 11295 07:59:29,080 --> 07:59:33,240 feed and insert into feeds ID created at 11296 07:59:33,240 --> 07:59:35,718 updated at name there will not be an API 11297 07:59:35,718 --> 07:59:40,638 key but let's see we need a name URL and 11298 07:59:40,638 --> 07:59:43,638 user ID okay name 11299 07:59:43,638 --> 07:59:45,840 URL user 11300 07:59:45,840 --> 07:59:48,760 ID we won't be generating an API key 11301 07:59:48,760 --> 07:59:51,798 here instead all of these values I think 11302 07:59:51,798 --> 07:59:53,558 we'll just be passed in from our 11303 07:59:53,558 --> 07:59:58,080 application code so 1 2 3 4 5 6 we need 11304 07:59:58,080 --> 08:00:02,120 six parameters for this function five 11305 08:00:02,120 --> 08:00:04,958 and six and then we'll just return uh 11306 08:00:04,958 --> 08:00:07,040 the entire feed row after it's done 11307 08:00:07,040 --> 08:00:08,680 being created and then I'll just 11308 08:00:08,680 --> 08:00:10,798 navigate back to the root of the 11309 08:00:10,798 --> 08:00:16,080 project and run SQL sqlc 11310 08:00:16,080 --> 08:00:19,000 generate to create the code for that new 11311 08:00:19,000 --> 08:00:21,398 query next we're going to create a new 11312 08:00:21,398 --> 08:00:24,318 Handler that will allow users of our API 11313 08:00:24,318 --> 08:00:27,160 to create a new feed here's the thing 11314 08:00:27,160 --> 08:00:29,958 that hand is also going to need all of 11315 08:00:29,958 --> 08:00:31,680 this same 11316 08:00:31,680 --> 08:00:34,680 logic that we have in the get user 11317 08:00:34,680 --> 08:00:37,318 Handler right we'll need to grab an 11318 08:00:37,318 --> 08:00:40,160 authentication uh token or an API key 11319 08:00:40,160 --> 08:00:42,798 from the authorization header fetch the 11320 08:00:42,798 --> 08:00:44,840 user and then use that user in the 11321 08:00:44,840 --> 08:00:46,638 Handler and rather than copying and 11322 08:00:46,638 --> 08:00:49,718 pasting uh this what 10 lines of code 11323 08:00:49,718 --> 08:00:51,680 into every Handler that's authenticated 11324 08:00:51,680 --> 08:00:53,318 instead we're going to build some 11325 08:00:53,318 --> 08:00:55,840 middleware to kind of dry up the code 11326 08:00:55,840 --> 08:00:58,318 right um let's go ahead and do that so 11327 08:00:58,318 --> 08:00:59,718 I'll create a new file I'm going to call 11328 08:00:59,718 --> 08:01:01,120 it 11329 08:01:01,120 --> 08:01:04,120 middleware 11330 08:01:04,120 --> 08:01:06,520 of.go art of the main 11331 08:01:06,520 --> 08:01:08,798 package and here we're going to define a 11332 08:01:08,798 --> 08:01:12,638 new type and it's our own custom type uh 11333 08:01:12,638 --> 08:01:15,878 I'm calling it off Handler and you'll 11334 08:01:15,878 --> 08:01:19,600 notice it looks almost exactly like a 11335 08:01:19,600 --> 08:01:22,120 regular HTTP Handler the only difference 11336 08:01:22,120 --> 08:01:25,080 is that it includes a third parameter it 11337 08:01:25,080 --> 08:01:28,000 has a user associated with it so if you 11338 08:01:28,000 --> 08:01:29,520 think about this um it makes a lot of 11339 08:01:29,520 --> 08:01:33,040 sense uh for any authenticated Handler 11340 08:01:33,040 --> 08:01:35,000 to accept three parameters where the 11341 08:01:35,000 --> 08:01:38,318 third one is the authenticated user now 11342 08:01:38,318 --> 08:01:41,318 the problem with this off Handler type 11343 08:01:41,318 --> 08:01:43,120 that we created is that it doesn't match 11344 08:01:43,120 --> 08:01:45,958 the function signature of an HTTP do 11345 08:01:45,958 --> 08:01:48,958 Handler Funk right uh those functions 11346 08:01:48,958 --> 08:01:51,200 with just the response writer and the 11347 08:01:51,200 --> 08:01:53,318 request as the only two parameters so 11348 08:01:53,318 --> 08:01:55,318 what we're going to do is create a new 11349 08:01:55,318 --> 08:01:58,478 function called middleware off uh that 11350 08:01:58,478 --> 08:02:00,878 works it's a method on our API config so 11351 08:02:00,878 --> 08:02:03,958 it has access to the database um but it 11352 08:02:03,958 --> 08:02:06,360 its job is to take an off Handler as 11353 08:02:06,360 --> 08:02:09,000 input and return a Handler Funk so that 11354 08:02:09,000 --> 08:02:11,920 we can you know use it with the CH 11355 08:02:11,920 --> 08:02:15,958 router okay let's Implement that the way 11356 08:02:15,958 --> 08:02:18,080 this function will actually work is 11357 08:02:18,080 --> 08:02:20,920 we're going to return a closure so we're 11358 08:02:20,920 --> 08:02:23,680 returning here a new Anonymous function 11359 08:02:23,680 --> 08:02:25,878 with that same function signature as 11360 08:02:25,878 --> 08:02:28,398 your normal HTTP Handler funk the 11361 08:02:28,398 --> 08:02:31,160 difference is that as we Define this 11362 08:02:31,160 --> 08:02:33,360 function we'll have access to everything 11363 08:02:33,360 --> 08:02:35,440 within the API config so we'll be able 11364 08:02:35,440 --> 08:02:37,638 to query the database so we can 11365 08:02:37,638 --> 08:02:39,760 basically just go rip out the code from 11366 08:02:39,760 --> 08:02:43,958 our get user Handler and paste it in 11367 08:02:43,958 --> 08:02:46,798 here right we're going to go get the API 11368 08:02:46,798 --> 08:02:50,398 key from the request well from the 11369 08:02:50,398 --> 08:02:52,958 request headers at least and then we can 11370 08:02:52,958 --> 08:02:57,200 go ahead and grab uh the user using that 11371 08:02:57,200 --> 08:02:58,638 API key 11372 08:02:58,638 --> 08:03:01,120 right so we'll have access to the user 11373 08:03:01,120 --> 08:03:03,718 here in the function finally all we need 11374 08:03:03,718 --> 08:03:07,080 to do is run the Handler that we were 11375 08:03:07,080 --> 08:03:10,200 given with the response writer the 11376 08:03:10,200 --> 08:03:13,478 request and the user right so by the 11377 08:03:13,478 --> 08:03:15,718 time we get to actually calling the a 11378 08:03:15,718 --> 08:03:19,718 Handler we're able to give it an actual 11379 08:03:19,718 --> 08:03:21,920 user from the database and this is 11380 08:03:21,920 --> 08:03:23,958 really great let me show you why so now 11381 08:03:23,958 --> 08:03:26,200 that the middle middleware o function 11382 08:03:26,200 --> 08:03:29,318 exists we can remove all of this code 11383 08:03:29,318 --> 08:03:32,600 from the get user Handler we can update 11384 08:03:32,600 --> 08:03:37,478 the get user Handler to accept as 11385 08:03:38,718 --> 08:03:41,160 input a database 11386 08:03:41,160 --> 08:03:44,558 user user database. 11387 08:03:44,558 --> 08:03:47,520 user look at how clean this function 11388 08:03:47,520 --> 08:03:49,840 becomes right now it's just now it's 11389 08:03:49,840 --> 08:03:52,200 literally just one line cool and now to 11390 08:03:52,200 --> 08:03:53,718 hook it up you'll notice we have an 11391 08:03:53,718 --> 08:03:56,240 error over here we just need to call our 11392 08:03:56,240 --> 08:03:58,920 middleware off 11393 08:03:58,920 --> 08:04:04,080 function apic CFG do middleware 11394 08:04:04,080 --> 08:04:07,558 off we call this function to convert the 11395 08:04:07,558 --> 08:04:11,600 get user Handler into a standard HTTP do 11396 08:04:11,600 --> 08:04:14,280 Handler funk I kind of move fast through 11397 08:04:14,280 --> 08:04:15,840 that hopefully it all make sense though 11398 08:04:15,840 --> 08:04:17,080 basically we're just calling the 11399 08:04:17,080 --> 08:04:20,120 middleware off function first to get the 11400 08:04:20,120 --> 08:04:22,958 authenticated user and then we're 11401 08:04:22,958 --> 08:04:25,558 calling that call back the the get user 11402 08:04:25,558 --> 08:04:27,440 Handler the nice thing is now we'll be 11403 08:04:27,440 --> 08:04:29,840 able to reuse that middleware across 11404 08:04:29,840 --> 08:04:33,160 many different HTTP Handler functions so 11405 08:04:33,160 --> 08:04:35,798 now let's create the create feed Handler 11406 08:04:35,798 --> 08:04:37,478 I'm going to go ahead and just copy this 11407 08:04:37,478 --> 08:04:41,160 Handler user change it to Handler 11408 08:04:41,160 --> 08:04:43,398 feed and for now we just need a create 11409 08:04:43,398 --> 08:04:45,878 function so I'll delete this get and 11410 08:04:45,878 --> 08:04:47,440 we'll call it 11411 08:04:47,440 --> 08:04:49,600 Handler create 11412 08:04:49,600 --> 08:04:52,318 feed and remember it's an authenticated 11413 08:04:52,318 --> 08:04:54,040 endpoint so we can have it accept the 11414 08:04:54,040 --> 08:04:58,520 user directly so user database. user 11415 08:04:58,520 --> 08:05:00,318 we know who's creating the feed by the 11416 08:05:00,318 --> 08:05:02,478 time we get to this function which is 11417 08:05:02,478 --> 08:05:05,398 awesome all right in order to create 11418 08:05:05,398 --> 08:05:08,520 create a feed use our new create feed 11419 08:05:08,520 --> 08:05:12,040 function which takes create feed 11420 08:05:12,040 --> 08:05:16,160 pams and create feed pams have ID 11421 08:05:16,160 --> 08:05:17,878 created at updated at name that's all 11422 08:05:17,878 --> 08:05:19,718 the same the difference is a URL and a 11423 08:05:19,718 --> 08:05:20,798 user 11424 08:05:20,798 --> 08:05:24,160 ID so 11425 08:05:24,280 --> 08:05:29,520 URL and a user ID which is a U ID uh 11426 08:05:29,520 --> 08:05:30,718 which actually exists already on the 11427 08:05:30,718 --> 08:05:33,638 user object so we can just do user. ID 11428 08:05:33,638 --> 08:05:36,718 okay um what do we want as input we need 11429 08:05:36,718 --> 08:05:38,638 a URL so we also are going to want a 11430 08:05:38,638 --> 08:05:41,240 prams 11431 08:05:47,080 --> 08:05:49,920 DOL so we want the user that's creating 11432 08:05:49,920 --> 08:05:52,360 a new feed to be able to just send us a 11433 08:05:52,360 --> 08:05:54,878 name and a URL and we'll go about 11434 08:05:54,878 --> 08:05:57,600 creating the entire uh kind of you know 11435 08:05:57,600 --> 08:05:59,920 feed object in the database or feed Row 11436 08:05:59,920 --> 08:06:00,760 in the 11437 08:06:00,760 --> 08:06:02,840 database so this is what our parameters 11438 08:06:02,840 --> 08:06:04,478 should look like uh what error am I 11439 08:06:04,478 --> 08:06:06,958 running into here cannot use API cf. 11440 08:06:06,958 --> 08:06:09,120 create 11441 08:06:09,120 --> 08:06:12,958 feed no new variables on left side of H 11442 08:06:12,958 --> 08:06:15,920 that's odd create feed should return a 11443 08:06:15,920 --> 08:06:19,680 feed let's take a look at that 11444 08:06:19,680 --> 08:06:22,478 definition yeah it does return a feed 11445 08:06:22,478 --> 08:06:25,398 what am I messing up 11446 08:06:25,718 --> 08:06:28,440 here oh first of all that shouldn't be a 11447 08:06:28,440 --> 08:06:30,360 user that should be a feed okay that's 11448 08:06:30,360 --> 08:06:32,080 the problem I was over I was trying to 11449 08:06:32,080 --> 08:06:35,160 overwrite the database. user type with a 11450 08:06:35,160 --> 08:06:37,080 feed type that won't 11451 08:06:37,080 --> 08:06:40,040 work okay so we're creating a feed we're 11452 08:06:40,040 --> 08:06:41,878 generating a new uid that's great we're 11453 08:06:41,878 --> 08:06:45,360 using the current time perfect um this 11454 08:06:45,360 --> 08:06:48,360 is getting messed up uh variable of Type 11455 08:06:48,360 --> 08:06:54,878 U id. uid as uu id. null U ID ah okay I 11456 08:06:54,878 --> 08:06:59,000 see the problem the create feed 11457 08:06:59,000 --> 08:07:02,920 pams except a uu id. null uuid that's a 11458 08:07:02,920 --> 08:07:05,760 problem we don't ever want a u the null 11459 08:07:05,760 --> 08:07:08,760 uuid type from the uid package is a 11460 08:07:08,760 --> 08:07:11,760 nullable uuid but we don't want it to be 11461 08:07:11,760 --> 08:07:14,318 nullable because we expect that every 11462 08:07:14,318 --> 08:07:16,318 feed will be created by a user so let's 11463 08:07:16,318 --> 08:07:18,878 go update 11464 08:07:18,878 --> 08:07:22,000 our our uh I think it's our is it our 11465 08:07:22,000 --> 08:07:25,240 migration let's go look schema 11466 08:07:25,240 --> 08:07:29,360 feeds yeah user 11467 08:07:29,360 --> 08:07:31,600 uid not 11468 08:07:31,600 --> 08:07:34,200 null cool it doesn't need to be unique a 11469 08:07:34,200 --> 08:07:35,638 user can have multiple feeds but it 11470 08:07:35,638 --> 08:07:39,360 should never be null all right um with 11471 08:07:39,360 --> 08:07:43,760 that we're actually going to need to 11472 08:07:43,878 --> 08:07:47,200 go uh rerun our migrations so 11473 08:07:47,200 --> 08:07:51,360 SQL um 11474 08:07:52,040 --> 08:07:56,360 schema and we'll do a down to drop the 11475 08:07:56,360 --> 08:07:58,558 table 11476 08:07:58,558 --> 08:08:01,280 down and then back up to create the new 11477 08:08:01,280 --> 08:08:03,798 table with the proper 11478 08:08:03,798 --> 08:08:06,958 schema and then we should 11479 08:08:06,958 --> 08:08:10,638 rerun SQL C 11480 08:08:10,638 --> 08:08:13,680 generate okay did that 11481 08:08:13,680 --> 08:08:16,318 work create feed create feed pams looks 11482 08:08:16,318 --> 08:08:18,840 like that error is gone it's now just a 11483 08:08:18,840 --> 08:08:22,120 uuid type perfect now at this point we 11484 08:08:22,120 --> 08:08:24,798 have a valid database feed should 11485 08:08:24,798 --> 08:08:26,280 probably update this error so that it 11486 08:08:26,280 --> 08:08:28,398 actually says feed um and we want to 11487 08:08:28,398 --> 08:08:32,520 return it um in our HTTP response 11488 08:08:32,520 --> 08:08:34,478 trouble is remember we don't want to 11489 08:08:34,478 --> 08:08:36,478 just directly return the struct let's go 11490 08:08:36,478 --> 08:08:38,718 create a new model for a 11491 08:08:38,718 --> 08:08:41,398 feed so we'll do 11492 08:08:41,398 --> 08:08:46,638 type feed and then I'm going to go just 11493 08:08:47,680 --> 08:08:52,558 copy the types from here and we'll use 11494 08:08:52,840 --> 08:08:55,798 those and we'll make our own Json tags 11495 08:08:55,798 --> 08:08:59,240 for the type 11496 08:09:02,120 --> 08:09:03,080 user 11497 08:09:03,080 --> 08:09:05,558 ID 11498 08:09:05,558 --> 08:09:12,520 URL name updated at and create at okay 11499 08:09:12,520 --> 08:09:15,878 and then we'll want 11500 08:09:15,920 --> 08:09:19,080 a what is it database 11501 08:09:19,080 --> 08:09:24,440 database feed to feed 11502 08:09:30,000 --> 08:09:33,160 and we'll return a 11503 08:09:42,920 --> 08:09:47,440 feed all of this should be pretty 11504 08:09:47,440 --> 08:09:49,120 straightforward and again this just 11505 08:09:49,120 --> 08:09:52,160 gives us more control right now we in 11506 08:09:52,160 --> 08:09:55,600 our code that's not generated by SQL c 11507 08:09:55,600 --> 08:09:59,080 um are able to Define you know what the 11508 08:09:59,080 --> 08:10:01,120 shape of the response will look like if 11509 08:10:01,120 --> 08:10:02,798 for whatever reason we needed to store 11510 08:10:02,798 --> 08:10:04,280 some data in the database but never 11511 08:10:04,280 --> 08:10:06,840 wanted to respond with it in our Json 11512 08:10:06,840 --> 08:10:08,920 API we could make those changes here in 11513 08:10:08,920 --> 08:10:11,000 this struct okay so now we've got 11514 08:10:11,000 --> 08:10:14,080 database feed to feed we'll call 11515 08:10:14,080 --> 08:10:18,040 that and now we should be good to go all 11516 08:10:18,040 --> 08:10:20,920 right let's test out our new Handler so 11517 08:10:20,920 --> 08:10:25,440 going to rebuild our server and run 11518 08:10:25,558 --> 08:10:29,160 it and over in the Thunder client let's 11519 08:10:29,160 --> 08:10:31,798 see so we just created a new user Joe so 11520 08:10:31,798 --> 08:10:34,080 we have our authentication key here or 11521 08:10:34,080 --> 08:10:39,360 our API key going to do a new request to 11522 08:10:39,360 --> 08:10:42,000 http 11523 08:10:42,000 --> 08:10:46,478 localhost 880 slv1 feeds ah now that I 11524 08:10:46,478 --> 08:10:48,600 type this out I realize that we never 11525 08:10:48,600 --> 08:10:49,558 hooked it 11526 08:10:49,558 --> 08:10:53,878 up let's go hook up that feed so feed 11527 08:10:53,878 --> 08:10:55,840 Handler Handler create feed we need to 11528 08:10:55,840 --> 08:10:58,520 go paste this in 11529 08:10:58,520 --> 08:11:02,120 to the main function so this one will go 11530 08:11:02,120 --> 08:11:04,840 under slash feeds because we're creating 11531 08:11:04,840 --> 08:11:07,478 a resource we're going to use a post 11532 08:11:07,478 --> 08:11:10,440 request Handler create 11533 08:11:10,440 --> 08:11:12,600 feed okay that should be hooked up now 11534 08:11:12,600 --> 08:11:15,600 let's uh restart our 11535 08:11:16,840 --> 08:11:20,798 server and over here again I need to 11536 08:11:20,798 --> 08:11:25,478 grab that API key all right 11537 08:11:27,760 --> 08:11:31,120 what do we want here post 11538 08:11:31,240 --> 08:11:36,040 request Local Host 8080 V1 11539 08:11:36,040 --> 08:11:40,558 feeds we do need to authenticate again 11540 08:11:40,558 --> 08:11:43,958 so qu 11541 08:11:44,360 --> 08:11:46,080 headers 11542 08:11:46,080 --> 08:11:47,920 auen 11543 08:11:47,920 --> 08:11:50,200 authorization API 11544 08:11:50,200 --> 08:11:52,680 key paste in that API 11545 08:11:52,680 --> 08:11:55,600 key okay uh what do we send in as the 11546 08:11:55,600 --> 08:11:57,798 body 11547 08:11:57,798 --> 08:12:00,398 let's take a look at our Handler again a 11548 08:12:00,398 --> 08:12:05,280 name and a URL okay so name now remember 11549 08:12:05,280 --> 08:12:07,558 this is this is this is not a person 11550 08:12:07,558 --> 08:12:11,478 this is a feed right and a feed is a URL 11551 08:12:11,478 --> 08:12:14,440 that kind of links to an RSS feed out on 11552 08:12:14,440 --> 08:12:16,318 the internet so this one I'm going to 11553 08:12:16,318 --> 08:12:19,638 put just uh Lanes Lan's 11554 08:12:19,638 --> 08:12:25,040 blog and then the URL is going to be 11555 08:12:25,040 --> 08:12:27,240 https 11556 08:12:27,240 --> 08:12:30,040 tags lane. 11557 08:12:30,040 --> 08:12:34,318 deev SL 11558 08:12:34,440 --> 08:12:36,520 index.xml so in case you're not familiar 11559 08:12:36,520 --> 08:12:38,360 with what an RSS feed is let me just 11560 08:12:38,360 --> 08:12:40,638 show you really quick um I'm here on my 11561 08:12:40,638 --> 08:12:43,240 blog Wags lane. deev and if you click 11562 08:12:43,240 --> 08:12:45,600 RSS up at the top it'll take you to my 11563 08:12:45,600 --> 08:12:49,718 RSS feed now every RSS feed um will have 11564 08:12:49,718 --> 08:12:51,958 a different URL it's kind of up to the 11565 08:12:51,958 --> 08:12:53,958 author of the blog or the podcast what 11566 08:12:53,958 --> 08:12:56,360 that feed URL is but you can usually 11567 08:12:56,360 --> 08:12:57,680 find it by poke looking around on their 11568 08:12:57,680 --> 08:12:59,840 website so in my case um it's just 11569 08:12:59,840 --> 08:13:03,520 waglan dodev index.xml and it will look 11570 08:13:03,520 --> 08:13:05,558 something like this if you open it up in 11571 08:13:05,558 --> 08:13:08,160 a browser it's basically this structured 11572 08:13:08,160 --> 08:13:11,718 XML document that describes what each 11573 08:13:11,718 --> 08:13:15,040 post on the blog says at least from a 11574 08:13:15,040 --> 08:13:16,478 high level it'll usually have something 11575 08:13:16,478 --> 08:13:18,760 like a link to the post maybe a short 11576 08:13:18,760 --> 08:13:21,600 description um basic stuff like that 11577 08:13:21,600 --> 08:13:24,638 again podcasts also work on the same RSS 11578 08:13:24,638 --> 08:13:26,318 structure so for testing you can use my 11579 08:13:26,318 --> 08:13:28,360 blog or if you know of any other RSS 11580 08:13:28,360 --> 08:13:31,440 feeds um out on the web you can use them 11581 08:13:31,440 --> 08:13:34,280 so now that I've pasted in that URL uh 11582 08:13:34,280 --> 08:13:36,718 let's go ahead and create that 11583 08:13:36,718 --> 08:13:39,920 feed and what do we get 11584 08:13:39,920 --> 08:13:43,080 back cool the feed's got a new URL 11585 08:13:43,080 --> 08:13:45,958 created at updated at the name and the 11586 08:13:45,958 --> 08:13:48,638 URL seem to have persisted correctly and 11587 08:13:48,638 --> 08:13:52,080 that is the user ID associated with the 11588 08:13:52,080 --> 08:13:54,840 API key that we use to create the feed 11589 08:13:54,840 --> 08:13:57,240 next we're going to add the ability for 11590 08:13:57,240 --> 08:14:00,318 any user to get all of the feeds in the 11591 08:14:00,318 --> 08:14:02,360 database this is not an authenticated 11592 08:14:02,360 --> 08:14:05,718 endpoint okay so we need new query I'm 11593 08:14:05,718 --> 08:14:07,958 going to go ahead and use the same file 11594 08:14:07,958 --> 08:14:10,680 um this query will just be called get 11595 08:14:10,680 --> 08:14:14,638 feeds and it will return many rows 11596 08:14:14,638 --> 08:14:17,638 instead of just one all right and this 11597 08:14:17,638 --> 08:14:21,360 one will be uh 11598 08:14:21,478 --> 08:14:24,120 select star from 11599 08:14:24,120 --> 08:14:27,360 feeds super super simple query here 11600 08:14:27,360 --> 08:14:28,718 we're just going to go grab all the 11601 08:14:28,718 --> 08:14:32,638 feeds and return them okay um from there 11602 08:14:32,638 --> 08:14:36,040 we should be able to sqlc 11603 08:14:36,040 --> 08:14:38,600 generate and let's go hook up that 11604 08:14:38,600 --> 08:14:41,840 Handler I'm going to use the same uh 11605 08:14:41,840 --> 08:14:44,878 Handler feed file U but this one will be 11606 08:14:44,878 --> 08:14:45,920 a little bit 11607 08:14:45,920 --> 08:14:49,558 different we going 11608 08:14:49,840 --> 08:14:55,520 to call this one Handler get 11609 08:14:55,520 --> 08:14:58,360 feeds it's not authenticated so we don't 11610 08:14:58,360 --> 08:15:00,760 need to pass in a user and it doesn't 11611 08:15:00,760 --> 08:15:02,638 even take any parameters right it's just 11612 08:15:02,638 --> 08:15:05,040 going to go get all of the feeds so um 11613 08:15:05,040 --> 08:15:07,558 apic 11614 08:15:25,920 --> 08:15:30,398 cfg.init' to return all of the feeds 11615 08:15:30,398 --> 08:15:33,558 this is not a single feed this is now a 11616 08:15:33,558 --> 08:15:36,958 slice of database. feeds so not only do 11617 08:15:36,958 --> 08:15:38,280 we need to return them but we need to 11618 08:15:38,280 --> 08:15:40,040 actually convert them so let's go update 11619 08:15:40,040 --> 08:15:42,440 our models a little bit let's create a 11620 08:15:42,440 --> 08:15:43,558 new 11621 08:15:43,558 --> 08:15:46,520 function this one will be database feeds 11622 08:15:46,520 --> 08:15:48,798 to 11623 08:15:48,798 --> 08:15:50,840 feeds and the difference is it will 11624 08:15:50,840 --> 08:15:52,680 accept a slice of database feeds and it 11625 08:15:52,680 --> 08:15:55,680 will'll return a slice of 11626 08:15:55,760 --> 08:15:58,760 feeds let's let's do this slice feed 11627 08:15:58,760 --> 08:16:00,600 we'll create a new empty slice of feeds 11628 08:16:00,600 --> 08:16:01,920 and then 11629 08:16:01,920 --> 08:16:05,558 four DB 11630 08:16:06,360 --> 08:16:10,558 feed range DB 11631 08:16:11,600 --> 08:16:15,798 feeds feeds equals 11632 08:16:15,798 --> 08:16:17,638 append 11633 08:16:17,638 --> 08:16:22,280 feeds database feeds or database feed 11634 08:16:22,280 --> 08:16:26,040 and return feeds sorry not we don't want 11635 08:16:26,040 --> 08:16:27,760 to append it directly we have to we have 11636 08:16:27,760 --> 08:16:31,638 to call our conversion function okay so 11637 08:16:31,638 --> 08:16:33,160 this function will just iterate over all 11638 08:16:33,160 --> 08:16:35,478 of the database feeds one by one 11639 08:16:35,478 --> 08:16:37,040 converting them into our new feed 11640 08:16:37,040 --> 08:16:39,840 structure and then returning them cool 11641 08:16:39,840 --> 08:16:42,120 now here we can use that 11642 08:16:42,120 --> 08:16:44,878 function to do that 11643 08:16:44,878 --> 08:16:48,440 mapping great let's hook up this Handler 11644 08:16:48,440 --> 08:16:52,638 so in main.go we'll create a new entry 11645 08:16:52,638 --> 08:16:57,280 here this is going to be a get request 11646 08:16:57,280 --> 08:17:00,040 and it's not 11647 08:17:00,760 --> 08:17:03,080 authenticated it will be 11648 08:17:03,080 --> 08:17:05,040 Handler yet 11649 08:17:05,040 --> 08:17:08,878 feeds cool let's regenerate I can't 11650 08:17:08,878 --> 08:17:10,600 remember if I generated my SQL C so I'll 11651 08:17:10,600 --> 08:17:13,238 do that couldn't hurt and then we'll 11652 08:17:13,238 --> 08:17:15,840 build and run the 11653 08:17:18,280 --> 08:17:20,478 server okay with that running let's go 11654 08:17:20,478 --> 08:17:24,120 ahead and create a couple more RSS feeds 11655 08:17:24,120 --> 08:17:25,398 so 11656 08:17:25,398 --> 08:17:28,600 here update the 11657 08:17:28,600 --> 08:17:31,280 body of my request sorry I'm so zoomed 11658 08:17:31,280 --> 08:17:32,638 in so that you guys can see and it just 11659 08:17:32,638 --> 08:17:33,760 makes it 11660 08:17:33,760 --> 08:17:37,760 hard um no this was to create users this 11661 08:17:37,760 --> 08:17:40,238 is users here's 11662 08:17:40,238 --> 08:17:43,638 feeds okay let's let's just add the same 11663 08:17:43,638 --> 08:17:46,638 URL with a couple well no we can't we 11664 08:17:46,638 --> 08:17:48,238 can't add the same URL let's just use 11665 08:17:48,238 --> 08:17:52,558 some garbage URLs just to test 11666 08:17:57,920 --> 08:17:59,200 all 11667 08:17:59,200 --> 08:18:03,120 right okay that created properly now 11668 08:18:03,120 --> 08:18:05,680 let's test our new 11669 08:18:05,680 --> 08:18:08,478 endpoint this one is going to be a get 11670 08:18:08,478 --> 08:18:11,200 request to feeds and we don't need to 11671 08:18:11,200 --> 08:18:13,958 add any authentication information okay 11672 08:18:13,958 --> 08:18:16,280 run 11673 08:18:16,878 --> 08:18:19,080 that awesome this looks good to me we've 11674 08:18:19,080 --> 08:18:21,238 got an array at the top level and then 11675 08:18:21,238 --> 08:18:23,958 two feed objects one for garbage blog 11676 08:18:23,958 --> 08:18:26,280 and one's for one for Lane's blog so it 11677 08:18:26,280 --> 08:18:28,200 looks like everything's working so we've 11678 08:18:28,200 --> 08:18:30,080 given users a way to create feeds and a 11679 08:18:30,080 --> 08:18:32,360 way to query all of the feeds now we're 11680 08:18:32,360 --> 08:18:34,238 going to give users a way to follow 11681 08:18:34,238 --> 08:18:36,360 specific feeds so that they can see kind 11682 08:18:36,360 --> 08:18:38,798 of an aggregated view of all of the 11683 08:18:38,798 --> 08:18:41,520 feeds that they care about on the system 11684 08:18:41,520 --> 08:18:44,878 okay so uh let's go ahead and add a new 11685 08:18:44,878 --> 08:18:48,200 migration we need a new table so this 11686 08:18:48,200 --> 08:18:50,040 will be the fourth migration and we'll 11687 08:18:50,040 --> 08:18:53,120 call this new table feed follows and 11688 08:18:53,120 --> 08:18:55,160 this table is just going to store the 11689 08:18:55,160 --> 08:18:57,638 relationship between a user and all of 11690 08:18:57,638 --> 08:18:59,238 the feeds they're following so it'll be 11691 08:18:59,238 --> 08:19:02,120 a many to many uh kind of table of user 11692 08:19:02,120 --> 08:19:04,080 IDs to feed 11693 08:19:04,080 --> 08:19:06,958 IDs all right um the table is going to 11694 08:19:06,958 --> 08:19:08,360 be called feed 11695 08:19:08,360 --> 08:19:11,280 follows so create table feed follows 11696 08:19:11,280 --> 08:19:13,718 every feed follow like every other 11697 08:19:13,718 --> 08:19:15,840 record in our database will have an ID a 11698 08:19:15,840 --> 08:19:18,760 created at and an updated at but its 11699 08:19:18,760 --> 08:19:20,478 unique Fields will be a little bit 11700 08:19:20,478 --> 08:19:22,478 different first it's going to need a 11701 08:19:22,478 --> 08:19:25,160 user 11702 08:19:25,200 --> 08:19:27,160 ID which is 11703 08:19:27,160 --> 08:19:30,638 is oh my gosh why can't I type fingers 11704 08:19:30,638 --> 08:19:32,760 the wrong place in the keyboard so a 11705 08:19:32,760 --> 08:19:37,280 user ID is a uu ID um that can be it 11706 08:19:37,280 --> 08:19:38,718 doesn't let's see it doesn't need to be 11707 08:19:38,718 --> 08:19:43,798 unique um but it does need to be not 11708 08:19:43,798 --> 08:19:47,478 null then we need a feed 11709 08:19:47,478 --> 08:19:52,200 ID also a uu ID not null and then we're 11710 08:19:52,200 --> 08:19:55,600 going to create a unique constraint on 11711 08:19:55,600 --> 08:20:00,000 the comb ination of user ID to feed ID 11712 08:20:00,000 --> 08:20:01,798 so 11713 08:20:01,798 --> 08:20:08,638 unique user ID feed ID so again this 11714 08:20:08,638 --> 08:20:10,280 constraint is going to make it so that 11715 08:20:10,280 --> 08:20:13,958 we can never have two instances of a 11716 08:20:13,958 --> 08:20:17,000 follow for the same user feed 11717 08:20:17,000 --> 08:20:19,360 relationship right you as a user can 11718 08:20:19,360 --> 08:20:21,520 only follow a certain feed once you 11719 08:20:21,520 --> 08:20:23,440 can't follow it twice that doesn't 11720 08:20:23,440 --> 08:20:24,600 really make sense right so we're going 11721 08:20:24,600 --> 08:20:26,760 to ensure that that's unique um also so 11722 08:20:26,760 --> 08:20:29,160 I missed a couple things here the user 11723 08:20:29,160 --> 08:20:32,120 ID uh should reference so 11724 08:20:32,120 --> 08:20:34,958 [Music] 11725 08:20:34,958 --> 08:20:38,040 references uh the users 11726 08:20:38,040 --> 08:20:42,718 table ID field and on delete we'll 11727 08:20:42,718 --> 08:20:46,000 Cascade so if a user is deleted we're 11728 08:20:46,000 --> 08:20:48,600 going to go delete all of the data about 11729 08:20:48,600 --> 08:20:49,958 what feeds they're 11730 08:20:49,958 --> 08:20:52,000 following um and then this one's going 11731 08:20:52,000 --> 08:20:54,878 to be very similar except it references 11732 08:20:54,878 --> 08:20:57,638 the feeds table 11733 08:20:57,638 --> 08:20:59,398 with its ID and again if a feed gets 11734 08:20:59,398 --> 08:21:01,318 deleted then we'll go delete all of the 11735 08:21:01,318 --> 08:21:04,840 following data related to that 11736 08:21:04,840 --> 08:21:08,398 feed cool okay let's go ahead and run 11737 08:21:08,398 --> 08:21:11,798 this migration so I'm going to go back 11738 08:21:11,798 --> 08:21:14,798 up into the SQL or I should say back 11739 08:21:14,798 --> 08:21:16,958 down into the SQL schema 11740 08:21:16,958 --> 08:21:19,040 directory and from 11741 08:21:19,040 --> 08:21:23,200 here I'll need my connection string do 11742 08:21:23,200 --> 08:21:24,798 goose 11743 08:21:24,798 --> 08:21:27,200 postgress connection string 11744 08:21:27,200 --> 08:21:29,120 ah I didn't grab the whole thing let's 11745 08:21:29,120 --> 08:21:31,318 try that 11746 08:21:31,318 --> 08:21:35,680 again all of that boo 11747 08:21:35,680 --> 08:21:38,000 postgress 11748 08:21:38,000 --> 08:21:41,958 up cool feed follows databases or feed 11749 08:21:41,958 --> 08:21:44,638 follows table is there so now we need a 11750 08:21:44,638 --> 08:21:48,040 way for users to follow feeds all right 11751 08:21:48,040 --> 08:21:49,798 let's go ahead and go create that so I'm 11752 08:21:49,798 --> 08:21:53,120 going to copy and paste the feed Handler 11753 08:21:53,120 --> 08:21:54,840 file and we'll call it 11754 08:21:54,840 --> 08:21:58,520 Handler feed 11755 08:21:58,520 --> 08:22:01,718 follows and update this so Handler 11756 08:22:01,718 --> 08:22:04,238 create feed follow so remember in order 11757 08:22:04,238 --> 08:22:06,680 for a user to follow a feed all we need 11758 08:22:06,680 --> 08:22:09,558 to do is create a new feed follow record 11759 08:22:09,558 --> 08:22:12,360 with that user feed 11760 08:22:12,360 --> 08:22:14,200 relationship okay this is an 11761 08:22:14,200 --> 08:22:16,680 authenticated endpoint right we so we we 11762 08:22:16,680 --> 08:22:18,718 need a user and we need them to be 11763 08:22:18,718 --> 08:22:21,878 authenticated have passed an API key 11764 08:22:21,878 --> 08:22:24,398 right and let's see what do we need them 11765 08:22:24,398 --> 08:22:27,440 to give us as input I think all we need 11766 08:22:27,440 --> 08:22:28,718 is a feed 11767 08:22:28,718 --> 08:22:31,160 ID right they just need to tell us which 11768 08:22:31,160 --> 08:22:32,840 feed they want 11769 08:22:32,840 --> 08:22:34,760 to 11770 08:22:34,760 --> 08:22:39,040 follow so a feed ID is a uu 11771 08:22:40,000 --> 08:22:43,398 ID all right and now we should be able 11772 08:22:43,398 --> 08:22:46,680 to create feed oh we we never we never 11773 08:22:46,680 --> 08:22:48,398 made we never made the squl query what 11774 08:22:48,398 --> 08:22:49,718 am I doing what am I doing I'm getting 11775 08:22:49,718 --> 08:22:52,638 way ahead of myself let's go add that 11776 08:22:52,638 --> 08:22:54,958 query quickly so 11777 08:22:54,958 --> 08:22:58,160 feed follows 11778 08:22:58,160 --> 08:23:02,318 and to start we'll need a create feed 11779 08:23:02,318 --> 08:23:05,080 follow okay what's in a feed follow 11780 08:23:05,080 --> 08:23:10,360 right got all these all of these fields 11781 08:23:10,360 --> 08:23:11,638 and I think yeah we're just going to 11782 08:23:11,638 --> 08:23:14,040 have them all past in directly that 11783 08:23:14,040 --> 08:23:17,440 seems like the easiest way so insert 11784 08:23:17,440 --> 08:23:18,760 into feed 11785 08:23:18,760 --> 08:23:22,318 follows ID created at updated 11786 08:23:22,318 --> 08:23:28,440 at user ID feed ID 11787 08:23:28,718 --> 08:23:30,558 that's five parameters right one two 11788 08:23:30,558 --> 08:23:33,760 three four five cool that looks 11789 08:23:33,760 --> 08:23:36,718 good now I should be able to go back and 11790 08:23:36,718 --> 08:23:39,958 run sqlc 11791 08:23:40,120 --> 08:23:43,040 generate cool now I should 11792 08:23:43,040 --> 08:23:45,280 have 11793 08:23:45,280 --> 08:23:50,000 a create feed follow function with 11794 08:23:50,000 --> 08:23:52,958 create feed follow 11795 08:23:52,958 --> 08:23:57,600 pams all right it accepts a user ID and 11796 08:23:57,600 --> 08:23:59,398 a feed ID so the user ID is just the 11797 08:23:59,398 --> 08:24:01,798 auth authenticated user the feed ID is 11798 08:24:01,798 --> 08:24:04,760 going to be passed in his params 11799 08:24:04,760 --> 08:24:09,398 right cool couldn't create feed 11800 08:24:09,638 --> 08:24:12,440 follow don't need a get Handler quite 11801 08:24:12,440 --> 08:24:14,840 yet and then we're going to just need to 11802 08:24:14,840 --> 08:24:18,200 make uh make that uh mapping function as 11803 08:24:18,200 --> 08:24:22,080 well for feed 11804 08:24:23,120 --> 08:24:25,600 follows so in our models file I'll 11805 08:24:25,600 --> 08:24:28,638 create a new feed follow struct and it's 11806 08:24:28,638 --> 08:24:34,120 going to have a user ID and a feed 11807 08:24:38,798 --> 08:24:43,638 ID and a new function database feed 11808 08:24:43,638 --> 08:24:49,120 follow to feed follow 11809 08:25:00,878 --> 08:25:04,360 all right DB feed 11810 08:25:13,280 --> 08:25:15,680 fall. by the way I'm not using GitHub 11811 08:25:15,680 --> 08:25:18,958 co-pilot in this video just so that you 11812 08:25:18,958 --> 08:25:22,080 could just just so you can see more of 11813 08:25:22,080 --> 08:25:24,760 my thought process um but I typically do 11814 08:25:24,760 --> 08:25:26,760 use GitHub co-pilot 11815 08:25:26,760 --> 08:25:29,920 and it makes this kind of function just 11816 08:25:29,920 --> 08:25:32,440 like way faster to write um it would 11817 08:25:32,440 --> 08:25:34,280 guess this kind of function almost 11818 08:25:34,280 --> 08:25:37,520 perfectly um so just so you know I I do 11819 08:25:37,520 --> 08:25:39,120 recommend those kinds of tools to speed 11820 08:25:39,120 --> 08:25:41,600 up the development process um I'm just 11821 08:25:41,600 --> 08:25:43,238 not using it uh right now so that you 11822 08:25:43,238 --> 08:25:45,238 can see how I think through you know 11823 08:25:45,238 --> 08:25:46,920 architecting this this application 11824 08:25:46,920 --> 08:25:48,760 without all the AI prompts getting in 11825 08:25:48,760 --> 08:25:52,200 the way okay now we should be able to 11826 08:25:52,200 --> 08:25:54,478 database feed follow to feed follow and 11827 08:25:54,478 --> 08:25:56,000 we're going to be clear that this is a 11828 08:25:56,000 --> 08:25:57,760 feed follow not a 11829 08:25:57,760 --> 08:26:01,200 feed and that goes 11830 08:26:01,200 --> 08:26:03,600 there 11831 08:26:03,600 --> 08:26:06,558 Perfect all right let's hook this up so 11832 08:26:06,558 --> 08:26:09,080 we're going to need to go into main.go 11833 08:26:09,080 --> 08:26:14,080 V1 router. poost is we're creating a 11834 08:26:14,080 --> 08:26:17,920 resource slash feed 11835 08:26:17,920 --> 08:26:21,160 follows and this is an 11836 08:26:21,160 --> 08:26:24,798 authenticated authenticated 11837 08:26:25,238 --> 08:26:29,200 Handler Handler create feed follow okay 11838 08:26:29,200 --> 08:26:31,360 let's test this new endpoint so we'll 11839 08:26:31,360 --> 08:26:33,920 build and run the 11840 08:26:36,760 --> 08:26:40,120 server and we'll need a new 11841 08:26:40,120 --> 08:26:44,760 request this one will be kind of similar 11842 08:26:44,760 --> 08:26:45,520 it'll 11843 08:26:45,520 --> 08:26:49,440 be oops a post request to the feed 11844 08:26:49,440 --> 08:26:52,000 follows end 11845 08:26:52,000 --> 08:26:55,200 point and we're going to need to 11846 08:26:55,200 --> 08:26:57,238 authenticate so let's go grab some 11847 08:26:57,238 --> 08:26:59,600 authentication 11848 08:26:59,600 --> 08:27:02,398 information let's see get users let's go 11849 08:27:02,398 --> 08:27:03,160 ahead 11850 08:27:03,160 --> 08:27:05,840 and send this couldn't get user sequel 11851 08:27:05,840 --> 08:27:09,318 no result okay I need to figure out what 11852 08:27:09,318 --> 08:27:11,920 users I have available to me oh that's 11853 08:27:11,920 --> 08:27:14,558 right we we changed this API key we 11854 08:27:14,558 --> 08:27:18,840 wanted it to break let's go create a new 11855 08:27:19,398 --> 08:27:22,440 user we'll make a new one 11856 08:27:22,440 --> 08:27:26,360 called uh Billy 11857 08:27:26,360 --> 08:27:28,798 and there's Billy's API 11858 08:27:28,798 --> 08:27:31,718 key cool we've got some 11859 08:27:31,718 --> 08:27:34,238 feeds but our feed 11860 08:27:34,238 --> 08:27:37,878 follows need an off 11861 08:27:37,878 --> 08:27:40,238 section sorry in the 11862 08:27:40,238 --> 08:27:42,558 headers we're doing it 11863 08:27:42,558 --> 08:27:44,878 manually 11864 08:27:44,878 --> 08:27:48,558 authorization API key there's Billy's 11865 08:27:48,558 --> 08:27:51,238 key and then in the body we need to pass 11866 08:27:51,238 --> 08:27:54,878 in the ID of the feed that we want to 11867 08:27:54,878 --> 08:27:58,000 follow so so let's do a get on all of 11868 08:27:58,000 --> 08:28:00,600 the feeds and we can follow either of 11869 08:28:00,600 --> 08:28:03,360 these let's follow Lane's 11870 08:28:03,360 --> 08:28:06,760 block there's our feed 11871 08:28:06,760 --> 08:28:11,600 ID paste that in there and 11872 08:28:12,680 --> 08:28:15,478 create amazing new ID for the feed 11873 08:28:15,478 --> 08:28:18,638 follow there's the user ID the feed ID 11874 08:28:18,638 --> 08:28:21,440 what happens if we try to recreate it 11875 08:28:21,440 --> 08:28:23,040 cool couldn't create feed follow 11876 08:28:23,040 --> 08:28:25,120 duplicate key value violates unique 11877 08:28:25,120 --> 08:28:26,718 constraint that's what we'd expect right 11878 08:28:26,718 --> 08:28:29,120 we shouldn't be able to follow the same 11879 08:28:29,120 --> 08:28:30,840 feed multiple times we're already 11880 08:28:30,840 --> 08:28:33,600 following it we already have a record uh 11881 08:28:33,600 --> 08:28:35,200 indicating that we are following it 11882 08:28:35,200 --> 08:28:37,200 everything appears to be working just 11883 08:28:37,200 --> 08:28:40,600 fine next let's give users a way to see 11884 08:28:40,600 --> 08:28:42,080 all of the different feeds that they are 11885 08:28:42,080 --> 08:28:48,638 currently following so we'll do get feed 11886 08:28:48,638 --> 08:28:51,760 follows and it will return 11887 08:28:51,760 --> 08:28:55,638 many and the query will be select star 11888 08:28:55,638 --> 08:28:57,760 from 11889 08:28:57,760 --> 08:29:03,398 e follows where user ID equals dollar 11890 08:29:03,398 --> 08:29:06,238 sign one right so get all the feed 11891 08:29:06,238 --> 08:29:09,398 follows for a given 11892 08:29:09,398 --> 08:29:12,080 ID let's get that hooked up need to run 11893 08:29:12,080 --> 08:29:16,000 SQL C generate to create that query and 11894 08:29:16,000 --> 08:29:19,878 then down here we'll create a new 11895 08:29:20,680 --> 08:29:24,878 Handler this Handler will also be 11896 08:29:24,878 --> 08:29:27,798 authenticated but it's going to be get 11897 08:29:27,798 --> 08:29:29,080 feed 11898 08:29:29,080 --> 08:29:32,200 follows have the user we don't need any 11899 08:29:32,200 --> 08:29:33,440 parameters 11900 08:29:33,440 --> 08:29:37,080 here and we're just going to call get 11901 08:29:37,080 --> 08:29:39,840 feed follows and we'll just need to pass 11902 08:29:39,840 --> 08:29:42,478 in the user's 11903 08:29:42,478 --> 08:29:47,360 ID couldn't get feed 11904 08:29:47,360 --> 08:29:50,080 follows cool now we've got a list of 11905 08:29:50,080 --> 08:29:52,398 feed follows or a slice of feed follows 11906 08:29:52,398 --> 08:29:54,160 so we're going to need to convert an 11907 08:29:54,160 --> 08:29:57,600 entire slice so again here we'll write 11908 08:29:57,600 --> 08:30:00,318 this type of a function it's going to be 11909 08:30:00,318 --> 08:30:02,318 database 11910 08:30:02,318 --> 08:30:05,200 feed 11911 08:30:05,200 --> 08:30:09,120 follows to feed 11912 08:30:21,440 --> 08:30:25,718 follows all right 11913 08:30:26,040 --> 08:30:30,040 lots of copying and pasting here feed 11914 08:30:35,558 --> 08:30:37,760 follows okay so now we have a way to 11915 08:30:37,760 --> 08:30:40,360 convert an entire slice of database feed 11916 08:30:40,360 --> 08:30:42,718 follows to our own 11917 08:30:42,718 --> 08:30:46,478 struct that looks good to 11918 08:30:47,160 --> 08:30:49,050 me there feed 11919 08:30:49,050 --> 08:30:50,238 [Music] 11920 08:30:50,238 --> 08:30:52,638 follows okay cool now we have a Handler 11921 08:30:52,638 --> 08:30:54,478 for getting feed follows let's go ahead 11922 08:30:54,478 --> 08:30:57,638 and update this 11923 08:30:57,638 --> 08:31:01,200 so we need a new V1 router. 11924 08:31:01,200 --> 08:31:06,160 getet SL feed 11925 08:31:06,878 --> 08:31:10,520 follows middle wear 11926 08:31:10,920 --> 08:31:13,238 off get feed 11927 08:31:13,238 --> 08:31:15,920 follows Perfect all right let's give 11928 08:31:15,920 --> 08:31:16,920 that a 11929 08:31:16,920 --> 08:31:21,878 shot so we'll build and run again 11930 08:31:27,280 --> 08:31:32,478 and now let's see so this is um this is 11931 08:31:32,478 --> 08:31:35,398 the request that we used to 11932 08:31:35,398 --> 08:31:38,080 create so let's 11933 08:31:38,080 --> 08:31:41,958 grab oh so hardworking on such a small 11934 08:31:41,958 --> 08:31:46,000 screen let's grab our API key and create 11935 08:31:46,000 --> 08:31:48,360 a new 11936 08:31:51,520 --> 08:31:56,360 request 80 slv1 feed follows it's going 11937 08:31:56,360 --> 08:32:00,160 to be a get request it does need to be 11938 08:32:03,120 --> 08:32:06,478 authenticated okay see if that 11939 08:32:06,478 --> 08:32:10,040 works cool we got the one feedback that 11940 08:32:10,040 --> 08:32:12,558 we are currently following finally we 11941 08:32:12,558 --> 08:32:15,398 need a way to unfollow feeds or to 11942 08:32:15,398 --> 08:32:17,680 delete feed follows so let's create a 11943 08:32:17,680 --> 08:32:19,440 new one new 11944 08:32:19,440 --> 08:32:24,398 query we'll do delete feed follow now 11945 08:32:24,398 --> 08:32:26,040 this one is going to be our first quy 11946 08:32:26,040 --> 08:32:27,878 that doesn't actually return 11947 08:32:27,878 --> 08:32:31,080 anything um it's just going to be an 11948 08:32:31,080 --> 08:32:32,840 execute right we're not returning one 11949 08:32:32,840 --> 08:32:34,478 record we're not returning many records 11950 08:32:34,478 --> 08:32:35,840 we're returning no records we're just 11951 08:32:35,840 --> 08:32:39,878 going to run a a SQL query so uh it'll 11952 08:32:39,878 --> 08:32:41,360 it's going to be 11953 08:32:41,360 --> 08:32:43,760 delete 11954 08:32:43,760 --> 08:32:46,478 from bead 11955 08:32:46,478 --> 08:32:52,360 follows where ID equals dollar sign one 11956 08:32:52,360 --> 08:32:57,318 and user ID equals sign too now it's 11957 08:32:57,318 --> 08:32:59,478 important it's important to point out 11958 08:32:59,478 --> 08:33:02,318 that we don't actually need the user ID 11959 08:33:02,318 --> 08:33:04,558 here for this query to work right the ID 11960 08:33:04,558 --> 08:33:07,398 is already a unique identifier the 11961 08:33:07,398 --> 08:33:10,680 reason I'm tacking on this user ID is 11962 08:33:10,680 --> 08:33:13,360 because this will prevent someone who 11963 08:33:13,360 --> 08:33:16,920 doesn't own a feed follow from trying to 11964 08:33:16,920 --> 08:33:19,520 unfollow a feed on behalf of somebody 11965 08:33:19,520 --> 08:33:24,160 else that makes sense uh if for whatever 11966 08:33:24,160 --> 08:33:26,238 reason another user 11967 08:33:26,238 --> 08:33:28,760 got access let's say if if for some 11968 08:33:28,760 --> 08:33:31,798 reason user B got access to the feed 11969 08:33:31,798 --> 08:33:33,920 follow ID of user 11970 08:33:33,920 --> 08:33:38,600 a if we didn't have this check here then 11971 08:33:38,600 --> 08:33:41,840 that user who hijacked a feed follow ID 11972 08:33:41,840 --> 08:33:43,920 would be able to like 11973 08:33:43,920 --> 08:33:46,920 unfollow like force the other user to do 11974 08:33:46,920 --> 08:33:49,318 an unfollow if that makes sense this 11975 08:33:49,318 --> 08:33:51,878 ensures that only the user who actually 11976 08:33:51,878 --> 08:33:54,958 owns the follow record can execute the 11977 08:33:54,958 --> 08:33:57,718 unfollow Comm command hope hopefully 11978 08:33:57,718 --> 08:34:01,200 that makes sense okay uh from here let's 11979 08:34:01,200 --> 08:34:04,680 just go ahead and generate 11980 08:34:05,000 --> 08:34:09,840 that and go hook it up to a new 11981 08:34:10,680 --> 08:34:14,238 endpoint so we'll do 11982 08:34:14,238 --> 08:34:17,680 Handler delete feed 11983 08:34:17,680 --> 08:34:19,760 follow now this one's going to be a 11984 08:34:19,760 --> 08:34:21,160 little 11985 08:34:21,160 --> 08:34:23,840 different in that it it is authenticated 11986 08:34:23,840 --> 08:34:27,360 but we need to get a feed follow ID and 11987 08:34:27,360 --> 08:34:29,878 delete requests so like HTTP delete 11988 08:34:29,878 --> 08:34:32,760 requests the delete HTTP method they 11989 08:34:32,760 --> 08:34:35,360 don't typically have a body in the 11990 08:34:35,360 --> 08:34:37,280 payload it's it's possible but I would 11991 08:34:37,280 --> 08:34:39,798 argue it's not super conventional um 11992 08:34:39,798 --> 08:34:41,440 it's a little more conventional to pass 11993 08:34:41,440 --> 08:34:45,638 the ID in the HTTP path so um it's going 11994 08:34:45,638 --> 08:34:48,680 to look something like 11995 08:34:50,600 --> 08:34:54,600 this view on router. delete feed follows 11996 08:34:54,600 --> 08:34:56,280 slash 11997 08:34:56,280 --> 08:34:59,478 feed follow 11998 08:34:59,478 --> 08:35:02,280 ID and then this will be 11999 08:35:02,280 --> 08:35:06,478 Handler uh Delete feed follow right so 12000 08:35:06,478 --> 08:35:09,398 we want the feed follow ID dynamically 12001 08:35:09,398 --> 08:35:12,638 passed in the path of the request so the 12002 08:35:12,638 --> 08:35:14,520 question is how do we grab this feed 12003 08:35:14,520 --> 08:35:18,160 follow ID um in our Handler itself well 12004 08:35:18,160 --> 08:35:21,160 the chai router has or Chi oh I'm I'm 12005 08:35:21,160 --> 08:35:23,478 never going to say that the proper way 12006 08:35:23,478 --> 08:35:26,558 uh the chi router has a I think it's p 12007 08:35:26,558 --> 08:35:29,440 is it URL let's see 12008 08:35:29,440 --> 08:35:33,798 URL parameter that's the one uh Ur URL 12009 08:35:33,798 --> 08:35:35,478 parameter function where we can pass in 12010 08:35:35,478 --> 08:35:37,958 the request and a key and in this case 12011 08:35:37,958 --> 08:35:39,638 it's going to have to match so feed 12012 08:35:39,638 --> 08:35:42,718 follow ID matches whatever we type in 12013 08:35:42,718 --> 08:35:45,520 here between the open and close 12014 08:35:45,520 --> 08:35:48,000 brackets okay and that's going to return 12015 08:35:48,000 --> 08:35:53,040 a string so this is the feed follow ID 12016 08:35:53,040 --> 08:35:54,878 string great we're going to take that 12017 08:35:54,878 --> 08:35:57,558 and we're going to par it into a uuid so 12018 08:35:57,558 --> 08:36:01,160 we'll do U id. 12019 08:36:01,160 --> 08:36:05,440 parse and that will return a feed follow 12020 08:36:05,440 --> 08:36:09,000 ID and potentially an 12021 08:36:09,798 --> 08:36:13,520 error if the error does not equal nil 12022 08:36:13,520 --> 08:36:19,520 we'll say couldn't parse feed follow 12023 08:36:19,520 --> 08:36:22,958 ID and that will be a 400 level errror 12024 08:36:22,958 --> 08:36:25,840 perfect okay from here we should be able 12025 08:36:25,840 --> 08:36:29,878 to do apic CFG do database. delete feed 12026 08:36:29,878 --> 08:36:32,840 follow and we need to pass in the 12027 08:36:32,840 --> 08:36:34,040 request 12028 08:36:34,040 --> 08:36:36,280 context 12029 08:36:36,280 --> 08:36:42,080 and feed follow params so database. feed 12030 08:36:42,080 --> 08:36:45,120 delete feed follow parameters it takes 12031 08:36:45,120 --> 08:36:47,520 an ID and a user ID so the ID of the 12032 08:36:47,520 --> 08:36:48,558 feed 12033 08:36:48,558 --> 08:36:52,638 follow we just parsed and then the user 12034 08:36:52,638 --> 08:36:55,040 ID comes in with that user object 12035 08:36:55,040 --> 08:36:57,238 because this is an authenticated 12036 08:36:57,238 --> 08:36:59,798 request cool and that should return just 12037 08:36:59,798 --> 08:37:01,958 an 12038 08:37:04,440 --> 08:37:06,920 error right oh we it's just it's just 12039 08:37:06,920 --> 08:37:08,318 giv me yellow squigglies because I need 12040 08:37:08,318 --> 08:37:09,798 to handle the 12041 08:37:09,798 --> 08:37:11,318 air 12042 08:37:11,318 --> 08:37:13,798 couldn't elete 12043 08:37:13,798 --> 08:37:15,798 speed 12044 08:37:15,798 --> 08:37:18,520 follow perfect uh what do we respond 12045 08:37:18,520 --> 08:37:19,680 with here I guess we have a couple 12046 08:37:19,680 --> 08:37:21,680 different options um the simplest thing 12047 08:37:21,680 --> 08:37:23,080 would just be to respond with like an 12048 08:37:23,080 --> 08:37:26,120 empty Json object I guess 12049 08:37:26,120 --> 08:37:28,638 uh what matters to the client is 12050 08:37:28,638 --> 08:37:32,160 probably the 200 Response Code um so we 12051 08:37:32,160 --> 08:37:34,318 could like for the sake of Simplicity 12052 08:37:34,318 --> 08:37:36,000 just so we can use our respond with Json 12053 08:37:36,000 --> 08:37:38,760 function we'll just return an empty Json 12054 08:37:38,760 --> 08:37:41,280 object alternatively maybe we could 12055 08:37:41,280 --> 08:37:44,600 return an object that says like message 12056 08:37:44,600 --> 08:37:46,958 you know unfollow successful or 12057 08:37:46,958 --> 08:37:49,958 something um but it it doesn't matter 12058 08:37:49,958 --> 08:37:51,680 too much I think as long as it's a 200 12059 08:37:51,680 --> 08:37:53,558 level code uh we're pretty much good to 12060 08:37:53,558 --> 08:37:55,558 go 12061 08:37:55,558 --> 08:37:57,238 okay and that's already been hooked 12062 08:37:57,238 --> 08:38:00,798 up so let's go ahead and test 12063 08:38:00,798 --> 08:38:02,920 it uh I can't remember if I generated 12064 08:38:02,920 --> 08:38:04,440 let me do that again and then we'll 12065 08:38:04,440 --> 08:38:06,958 restart the 12066 08:38:07,798 --> 08:38:11,600 server and take a 12067 08:38:11,600 --> 08:38:15,798 look okay so this was our endpoint it's 12068 08:38:15,798 --> 08:38:18,080 returning the feeds that we're currently 12069 08:38:18,080 --> 08:38:21,398 following let's go ahead and delete this 12070 08:38:21,398 --> 08:38:25,958 feed follow so we need new request 12071 08:38:27,840 --> 08:38:30,080 this is going to be a delete request 12072 08:38:30,080 --> 08:38:32,318 we're going to unfollow a specific ID 12073 08:38:32,318 --> 08:38:35,000 we're going to unfollow this we're going 12074 08:38:35,000 --> 08:38:37,958 to delete this feed follow right feed 12075 08:38:37,958 --> 08:38:40,280 follow with that with that 12076 08:38:40,280 --> 08:38:43,120 ID and the headers we do need to be 12077 08:38:43,120 --> 08:38:46,760 authenticated as the same 12078 08:38:48,840 --> 08:38:52,280 person so 12079 08:38:54,360 --> 08:38:58,360 authorization same API key okay let's 12080 08:38:58,360 --> 08:39:02,000 run that delete we got a 200 response 12081 08:39:02,000 --> 08:39:04,718 now let's go do a get and make sure that 12082 08:39:04,718 --> 08:39:09,040 it's gone yep empty list or empty array 12083 08:39:09,040 --> 08:39:11,280 we're good to go okay we've built out 12084 08:39:11,280 --> 08:39:14,398 the majority of the crud section of our 12085 08:39:14,398 --> 08:39:16,318 API but we haven't built the most 12086 08:39:16,318 --> 08:39:18,160 interesting part which is the part of 12087 08:39:18,160 --> 08:39:20,238 the server that actually goes out and 12088 08:39:20,238 --> 08:39:22,638 fetches posts from the different RSS 12089 08:39:22,638 --> 08:39:25,440 feeds that exist in our database again 12090 08:39:25,440 --> 08:39:27,440 the whole purpose of this server that 12091 08:39:27,440 --> 08:39:29,360 we're building is so that it can keep 12092 08:39:29,360 --> 08:39:31,360 track of all of these different feeds in 12093 08:39:31,360 --> 08:39:33,160 the database and then go out 12094 08:39:33,160 --> 08:39:35,680 periodically and actually download all 12095 08:39:35,680 --> 08:39:38,840 of the posts that are on each individual 12096 08:39:38,840 --> 08:39:40,958 feed so for example we have a feed for 12097 08:39:40,958 --> 08:39:43,558 my personal blog post this server will 12098 08:39:43,558 --> 08:39:46,478 actually go out to my blog every I don't 12099 08:39:46,478 --> 08:39:48,840 know 10 minutes and check to see if 12100 08:39:48,840 --> 08:39:51,558 there's a new blog post to download and 12101 08:39:51,558 --> 08:39:53,638 store in the database so the first thing 12102 08:39:53,638 --> 08:39:57,200 we need to do is update the feeds table 12103 08:39:57,200 --> 08:39:59,558 to have one more column we need a new 12104 08:39:59,558 --> 08:40:02,318 column called last fetched at and it's 12105 08:40:02,318 --> 08:40:04,200 just so we can keep track of when we 12106 08:40:04,200 --> 08:40:06,878 last fetched the posts for a given feed 12107 08:40:06,878 --> 08:40:07,878 so let's go ahead and add that we'll 12108 08:40:07,878 --> 08:40:10,638 need new migration um and it will look 12109 08:40:10,638 --> 08:40:12,878 kind of like this migration uh it's 12110 08:40:12,878 --> 08:40:15,558 going to be our fifth migration so far 12111 08:40:15,558 --> 08:40:17,558 it's going to be on the feeds table and 12112 08:40:17,558 --> 08:40:19,958 we're going to be adding the last 12113 08:40:19,958 --> 08:40:25,878 fetched at last fetched at field okay so 12114 08:40:25,878 --> 08:40:30,160 alter table feeds add column last 12115 08:40:30,160 --> 08:40:33,120 fetched 12116 08:40:33,238 --> 08:40:37,398 at and this one is going to 12117 08:40:37,398 --> 08:40:39,398 be 12118 08:40:39,398 --> 08:40:41,840 timestamp and it will be nullable so we 12119 08:40:41,840 --> 08:40:45,000 don't need a notnull constraint 12120 08:40:45,000 --> 08:40:47,878 um in fact that's it 12121 08:40:47,878 --> 08:40:50,200 um it's okay like we don't need to 12122 08:40:50,200 --> 08:40:52,080 specify any defaults uh that should be 12123 08:40:52,080 --> 08:40:54,520 it um and then as far as the down 12124 08:40:54,520 --> 08:40:57,520 migration goes we'll just be deleting or 12125 08:40:57,520 --> 08:41:00,440 dropping the column from the feeds table 12126 08:41:00,440 --> 08:41:05,280 okay cool let's run that 12127 08:41:06,000 --> 08:41:10,360 migration so Goose 12128 08:41:15,680 --> 08:41:18,558 postgress perfect so we don't need to 12129 08:41:18,558 --> 08:41:21,440 update the create feed uh 12130 08:41:21,440 --> 08:41:24,160 function we want the last fetch St field 12131 08:41:24,160 --> 08:41:25,878 to default to null so no changes are 12132 08:41:25,878 --> 08:41:28,280 necessary there but we do need a new we 12133 08:41:28,280 --> 08:41:29,798 do need a new query this one's going to 12134 08:41:29,798 --> 08:41:31,840 be 12135 08:41:31,840 --> 08:41:37,120 called get next oh my gosh get next feed 12136 08:41:37,120 --> 08:41:39,920 to fetch can't type today get next feed 12137 08:41:39,920 --> 08:41:42,280 to fetch and it will return a single 12138 08:41:42,280 --> 08:41:45,440 row and this one should say select 12139 08:41:45,440 --> 08:41:49,040 star from 12140 08:41:49,080 --> 08:41:51,398 feeds order 12141 08:41:51,398 --> 08:41:56,120 by last fetched at descending 12142 08:41:56,120 --> 08:41:57,958 NS 12143 08:41:57,958 --> 08:42:01,238 first limit 12144 08:42:01,238 --> 08:42:05,080 one okay so we always this the purpose 12145 08:42:05,080 --> 08:42:07,318 of this function is to go get the feed 12146 08:42:07,318 --> 08:42:10,558 that next needs to be fetched like we 12147 08:42:10,558 --> 08:42:14,238 need to go get posts for this feed next 12148 08:42:14,238 --> 08:42:17,160 and the whole idea is first we want to 12149 08:42:17,160 --> 08:42:19,160 go find any feeds that have never been 12150 08:42:19,160 --> 08:42:20,798 fetched before those need to take 12151 08:42:20,798 --> 08:42:24,080 priority after that if every feed has 12152 08:42:24,080 --> 08:42:26,440 been fetched then we want to go find the 12153 08:42:26,440 --> 08:42:29,000 one that was fetched the longest ago 12154 08:42:29,000 --> 08:42:31,000 like the farthest in the past right so 12155 08:42:31,000 --> 08:42:33,280 we're ordering by last fetched at um 12156 08:42:33,280 --> 08:42:37,200 nulls first in descending 12157 08:42:37,200 --> 08:42:39,558 order actually scratch that we're going 12158 08:42:39,558 --> 08:42:43,000 to want to do a ascending right 12159 08:42:43,000 --> 08:42:45,840 ascending would put the lowest the 12160 08:42:45,840 --> 08:42:47,520 smallest time stamps right the ones 12161 08:42:47,520 --> 08:42:50,080 further in the past at the top and then 12162 08:42:50,080 --> 08:42:54,160 Ascend into the present okay so order by 12163 08:42:54,160 --> 08:42:57,200 last fetch thatat ascend ending NS first 12164 08:42:57,200 --> 08:42:59,200 perfect okay just to make sure that my 12165 08:42:59,200 --> 08:43:02,440 SQL code is valid we'll generate that 12166 08:43:02,440 --> 08:43:04,680 looks good okay next we need one more 12167 08:43:04,680 --> 08:43:06,638 query this one will be 12168 08:43:06,638 --> 08:43:09,840 called uh Mark feed 12169 08:43:09,840 --> 08:43:13,080 fetched Mark feed I guess as 12170 08:43:13,080 --> 08:43:15,080 fetched this is the one we'll call after 12171 08:43:15,080 --> 08:43:17,238 we fetch a feed to say that we fetched 12172 08:43:17,238 --> 08:43:21,120 it um and we'll return the updated feed 12173 08:43:21,120 --> 08:43:22,760 okay so it's going to be 12174 08:43:22,760 --> 08:43:26,000 update feeds 12175 08:43:26,000 --> 08:43:30,000 set last fetched at equal to 12176 08:43:30,000 --> 08:43:36,080 now and updated at also equal to now so 12177 08:43:36,080 --> 08:43:37,840 we haven't really gone over this but the 12178 08:43:37,840 --> 08:43:39,718 updated at and created at fields are 12179 08:43:39,718 --> 08:43:41,718 mostly for auditing purposes it's pretty 12180 08:43:41,718 --> 08:43:44,638 standard practice to set these fields on 12181 08:43:44,638 --> 08:43:46,760 basically every record in an SQL 12182 08:43:46,760 --> 08:43:48,878 database just so you can see when 12183 08:43:48,878 --> 08:43:50,840 they've been created and updated it's 12184 08:43:50,840 --> 08:43:52,718 kind of again auditing 12185 08:43:52,718 --> 08:43:57,040 purposes okay uh where 12186 08:43:57,040 --> 08:44:00,840 ID equals dollar sign 12187 08:44:00,840 --> 08:44:02,680 one 12188 08:44:02,680 --> 08:44:05,680 and returning 12189 08:44:05,680 --> 08:44:09,040 star okay so we update the feeds we set 12190 08:44:09,040 --> 08:44:10,958 the last fetch at and the updated at to 12191 08:44:10,958 --> 08:44:14,280 the current time for the given ID that 12192 08:44:14,280 --> 08:44:15,520 looks good to me let's go ahead and 12193 08:44:15,520 --> 08:44:19,440 generate that perfect next we need a way 12194 08:44:19,440 --> 08:44:23,000 to kind of take an RSS URL or a feed URL 12195 08:44:23,000 --> 08:44:26,160 and parse it into an an actual response 12196 08:44:26,160 --> 08:44:27,958 body and in this case we're going to 12197 08:44:27,958 --> 08:44:29,840 represent it as a struct let me show you 12198 08:44:29,840 --> 08:44:32,040 what I mean so let's create a new file 12199 08:44:32,040 --> 08:44:35,878 I'm just going to call it rs. 12200 08:44:36,080 --> 08:44:40,000 Go and it's going to be part of the main 12201 08:44:40,000 --> 08:44:42,958 package and we need a new function and 12202 08:44:42,958 --> 08:44:45,920 we're going to call it RSS 12203 08:44:45,920 --> 08:44:49,040 to or actually let's call it 12204 08:44:49,040 --> 08:44:51,718 url url to 12205 08:44:51,718 --> 08:44:53,558 feed 12206 08:44:53,558 --> 08:44:57,478 okay and it's going to take as input a 12207 08:44:57,478 --> 08:45:00,360 URL which is just a string and it will 12208 08:45:00,360 --> 08:45:02,760 return a new type so we need to specify 12209 08:45:02,760 --> 08:45:07,958 the new type type um RSS 12210 08:45:08,478 --> 08:45:12,360 feed it will return both an RSS feed and 12211 08:45:12,360 --> 08:45:13,520 potentially an error if there's 12212 08:45:13,520 --> 08:45:15,318 something wrong uh with the request that 12213 08:45:15,318 --> 08:45:19,160 it's making now that RSS feed struct 12214 08:45:19,160 --> 08:45:20,558 that we just created is going to 12215 08:45:20,558 --> 08:45:23,558 represent basically this giant this 12216 08:45:23,558 --> 08:45:25,878 giant document here right so if you go 12217 08:45:25,878 --> 08:45:29,878 to Wags lane. deev index.xml which is a 12218 08:45:29,878 --> 08:45:33,318 valid RSS feed then you'll see this 12219 08:45:33,318 --> 08:45:35,120 giant document and really you can think 12220 08:45:35,120 --> 08:45:38,478 of RSS as just structured data in XML 12221 08:45:38,478 --> 08:45:40,958 format and XML is just kind of like 12222 08:45:40,958 --> 08:45:44,520 crappy Json so the way we parse XML in 12223 08:45:44,520 --> 08:45:48,000 go is very similar to The Way We parse 12224 08:45:48,000 --> 08:45:50,200 Json let me show you what I mean I've 12225 08:45:50,200 --> 08:45:52,200 done the Dirty Work of scanning all of 12226 08:45:52,200 --> 08:45:56,000 the valid um values in that big RSS 12227 08:45:56,000 --> 08:45:58,840 document and I found that basically 12228 08:45:58,840 --> 08:46:00,160 these are the 12229 08:46:00,160 --> 08:46:05,638 keys um for the RSS entries in my blog 12230 08:46:05,638 --> 08:46:09,000 so RSS is kind of a standardized set of 12231 08:46:09,000 --> 08:46:12,000 keys within XML um and basically what 12232 08:46:12,000 --> 08:46:13,680 I'm saying is these are the keys that we 12233 08:46:13,680 --> 08:46:15,440 care about right at the top level of an 12234 08:46:15,440 --> 08:46:19,238 RSS feed we expect a channel key right 12235 08:46:19,238 --> 08:46:21,318 in the XML document and we expect a 12236 08:46:21,318 --> 08:46:23,040 channel to have a title a link a 12237 08:46:23,040 --> 08:46:26,238 description a language and then a slice 12238 08:46:26,238 --> 08:46:28,638 of items and then items are kind of 12239 08:46:28,638 --> 08:46:30,520 these nested objects that each have 12240 08:46:30,520 --> 08:46:32,878 their own title link descriptions and 12241 08:46:32,878 --> 08:46:35,600 publication dates right and each item is 12242 08:46:35,600 --> 08:46:38,478 a new blog post and if you're asking how 12243 08:46:38,478 --> 08:46:41,440 I came up with those names of all of the 12244 08:46:41,440 --> 08:46:42,680 different Keys it's because I went and 12245 08:46:42,680 --> 08:46:44,638 looked here in this document I saw okay 12246 08:46:44,638 --> 08:46:46,958 at the top level we have a channel right 12247 08:46:46,958 --> 08:46:49,318 and then we have um this entry with a 12248 08:46:49,318 --> 08:46:52,318 title a link a description right so I 12249 08:46:52,318 --> 08:46:54,120 just kind of manually looked through 12250 08:46:54,120 --> 08:46:56,160 this document and found all the stuff 12251 08:46:56,160 --> 08:46:58,080 that I wanted to parse out so let's fill 12252 08:46:58,080 --> 08:47:00,958 in the rest of this URL to feed function 12253 08:47:00,958 --> 08:47:02,718 so first we're going to need an HTTP 12254 08:47:02,718 --> 08:47:05,318 client um I'm just creating a new client 12255 08:47:05,318 --> 08:47:07,558 using the HTTP Library um we'll set it 12256 08:47:07,558 --> 08:47:09,280 to a timeout of 10 seconds if it takes 12257 08:47:09,280 --> 08:47:11,280 more than 10 seconds to fetch an RSS 12258 08:47:11,280 --> 08:47:13,478 feed uh we don't want that feed anyway 12259 08:47:13,478 --> 08:47:16,398 probably broken okay uh then we can use 12260 08:47:16,398 --> 08:47:19,280 that client to make a get request 12261 08:47:19,280 --> 08:47:22,638 to the URL of the feed and that's going 12262 08:47:22,638 --> 08:47:25,440 to return an HTTP response and 12263 08:47:25,440 --> 08:47:28,040 potentially an 12264 08:47:28,080 --> 08:47:30,760 error if there's an error we'll just 12265 08:47:30,760 --> 08:47:32,920 return let's just 12266 08:47:32,920 --> 08:47:36,558 do um for cons for ease of use I'm going 12267 08:47:36,558 --> 08:47:38,360 to make this a pointer to an RSS feed so 12268 08:47:38,360 --> 08:47:41,440 we can just return nil and the 12269 08:47:41,440 --> 08:47:45,080 airor cool um if everything's okay then 12270 08:47:45,080 --> 08:47:47,520 we're going to defer a 12271 08:47:47,520 --> 08:47:51,760 close on let's close on the resp sorry 12272 08:47:51,760 --> 08:47:53,398 it's not it's not the close function 12273 08:47:53,398 --> 08:47:56,760 it's resp. body 12274 08:47:57,878 --> 08:48:00,440 close Okay and then after that we want 12275 08:48:00,440 --> 08:48:03,600 to get all of the data from the response 12276 08:48:03,600 --> 08:48:06,398 body so it's going to be io. readall we 12277 08:48:06,398 --> 08:48:10,520 have to read everything from resp. body 12278 08:48:10,520 --> 08:48:13,080 and that comes back as a slice of bites 12279 08:48:13,080 --> 08:48:15,478 and an 12280 08:48:18,000 --> 08:48:21,520 error okay this slice of bytes we want 12281 08:48:21,520 --> 08:48:23,200 to read 12282 08:48:23,200 --> 08:48:27,840 into this RSS feed so dealing with XML 12283 08:48:27,840 --> 08:48:31,718 in go is very similar to dealing with 12284 08:48:31,718 --> 08:48:34,160 Json and go it's actually going to be 12285 08:48:34,160 --> 08:48:36,160 XML 12286 08:48:36,160 --> 08:48:37,680 dot 12287 08:48:37,680 --> 08:48:41,238 unmarshall pass in the data and a 12288 08:48:41,238 --> 08:48:43,680 pointer to where we want to unmarshal 12289 08:48:43,680 --> 08:48:44,920 the data so actually I need to create an 12290 08:48:44,920 --> 08:48:47,520 empty struct we need RSS 12291 08:48:47,520 --> 08:48:51,520 feed is an empty RSS feed 12292 08:48:51,520 --> 08:48:55,200 struct then we'll unmarshall into that 12293 08:48:55,200 --> 08:48:56,718 location in 12294 08:48:56,718 --> 08:49:00,360 memory that will return an 12295 08:49:00,360 --> 08:49:02,680 error if everything goes well then we 12296 08:49:02,680 --> 08:49:07,878 can just return the new populated RSS 12297 08:49:10,558 --> 08:49:13,798 feed perfect now as I type this out I'm 12298 08:49:13,798 --> 08:49:15,840 already kind of dissatisfied with this 12299 08:49:15,840 --> 08:49:17,238 pointer solution I don't think that 12300 08:49:17,238 --> 08:49:19,080 needs to be a pointer I think we should 12301 08:49:19,080 --> 08:49:21,760 just return empty 12302 08:49:21,760 --> 08:49:24,840 structs um either way would work I think 12303 08:49:24,840 --> 08:49:26,360 this is a little cleaner though because 12304 08:49:26,360 --> 08:49:29,958 it means the user of this function us 12305 08:49:29,958 --> 08:49:32,080 right uh will will get an actual RSS 12306 08:49:32,080 --> 08:49:33,760 feedback and not a pointer to an RSS 12307 08:49:33,760 --> 08:49:35,958 feed okay let's go ahead and test this 12308 08:49:35,958 --> 08:49:37,318 really quick I'm just going to do a 12309 08:49:37,318 --> 08:49:40,120 little kind of hacky 12310 08:49:40,120 --> 08:49:42,478 thing just right at the top of main I'm 12311 08:49:42,478 --> 08:49:45,558 going to call URL to feed and give it 12312 08:49:45,558 --> 08:49:51,000 the URL of um my blog so waglan 12313 08:49:51,000 --> 08:49:55,000 dodev index.xml 12314 08:49:55,000 --> 08:49:58,760 that should return a feed and an 12315 08:49:58,760 --> 08:50:04,000 error right and then if error not equal 12316 08:50:04,000 --> 08:50:06,360 nil log. 12317 08:50:06,360 --> 08:50:09,398 fatal error otherwise I want to just 12318 08:50:09,398 --> 08:50:14,120 print out fmt do print line let's just 12319 08:50:14,120 --> 08:50:15,638 print out the whole feed it'll be 12320 08:50:15,638 --> 08:50:17,920 disgusting but at least we'll get to see 12321 08:50:17,920 --> 08:50:21,200 if it kind of worked okay let's build 12322 08:50:21,200 --> 08:50:24,718 and run that 12323 08:50:30,718 --> 08:50:32,200 there we 12324 08:50:32,200 --> 08:50:35,160 go cool so if you kind of scroll through 12325 08:50:35,160 --> 08:50:37,520 this you'll see it looks like I mean 12326 08:50:37,520 --> 08:50:39,600 there was no errors and then it looks 12327 08:50:39,600 --> 08:50:41,318 like we 12328 08:50:41,318 --> 08:50:44,200 properly at least you know at first 12329 08:50:44,200 --> 08:50:45,638 glance looks like we properly filled out 12330 08:50:45,638 --> 08:50:47,638 that struct it's kind of just dumping 12331 08:50:47,638 --> 08:50:50,360 all of the data so now that we've done a 12332 08:50:50,360 --> 08:50:53,398 sanity test on our URL to feed function 12333 08:50:53,398 --> 08:50:55,520 let's go write the actual ual 12334 08:50:55,520 --> 08:51:00,600 scraper create a new file just call this 12335 08:51:19,440 --> 08:51:22,200 scraper.com so we can really see so we 12336 08:51:22,200 --> 08:51:25,040 can actually see what uh what we're 12337 08:51:25,040 --> 08:51:27,080 dealing with here so it'll take three 12338 08:51:27,080 --> 08:51:31,360 inputs a connection to the database um a 12339 08:51:31,360 --> 08:51:32,840 number of 12340 08:51:32,840 --> 08:51:35,238 concurrency units I guess the best way 12341 08:51:35,238 --> 08:51:36,638 to think about this is how many 12342 08:51:36,638 --> 08:51:38,760 different go routines we want to do the 12343 08:51:38,760 --> 08:51:43,120 scraping on and then how much time uh we 12344 08:51:43,120 --> 08:51:45,200 want in between each request to go 12345 08:51:45,200 --> 08:51:49,318 scrape a new RSS feed cool and it 12346 08:51:49,318 --> 08:51:50,600 shouldn't return anything because this 12347 08:51:50,600 --> 08:51:52,840 is going to be a long running job now 12348 08:51:52,840 --> 08:51:54,840 because this worker this scrap rper is 12349 08:51:54,840 --> 08:51:56,160 going to be running in the background of 12350 08:51:56,160 --> 08:51:57,680 our server I think it's really important 12351 08:51:57,680 --> 08:51:59,920 that we have good logging um that kind 12352 08:51:59,920 --> 08:52:02,238 of tells us what's going on as it's 12353 08:52:02,238 --> 08:52:04,718 happening so when we start scraping I'm 12354 08:52:04,718 --> 08:52:07,398 going to do a a little log message here 12355 08:52:07,398 --> 08:52:09,280 so log. 12356 08:52:09,280 --> 08:52:13,200 printf we say 12357 08:52:13,200 --> 08:52:18,558 scraping on percent V go 12358 08:52:18,558 --> 08:52:24,878 routines every percent s duration 12359 08:52:24,878 --> 08:52:27,120 pass in the concurrency and the time 12360 08:52:27,120 --> 08:52:28,718 between 12361 08:52:28,718 --> 08:52:32,280 requests cool after that we need to 12362 08:52:32,280 --> 08:52:34,718 figure out like how we're going to make 12363 08:52:34,718 --> 08:52:37,798 our requests on this interval and 12364 08:52:37,798 --> 08:52:40,718 there's a really cool um mechanism in 12365 08:52:40,718 --> 08:52:42,478 the standard library and go called a 12366 08:52:42,478 --> 08:52:45,920 ticker so we can create a new ticker uh 12367 08:52:45,920 --> 08:52:48,478 using the standard Library so time. new 12368 08:52:48,478 --> 08:52:50,798 ticker and we give it a duration in this 12369 08:52:50,798 --> 08:52:53,238 case time between 12370 08:52:53,238 --> 08:52:56,840 requests and it responds with a 12371 08:52:56,840 --> 08:53:00,760 ticker and then we can use a for 12372 08:53:00,760 --> 08:53:04,680 Loop to execute the body of the for Loop 12373 08:53:04,680 --> 08:53:08,160 every time a new value comes across the 12374 08:53:08,160 --> 08:53:10,638 ticker's channel so the ticker Has a 12375 08:53:10,638 --> 08:53:14,798 Field called C which is a channel where 12376 08:53:14,798 --> 08:53:17,280 every kind of let's say that you know 12377 08:53:17,280 --> 08:53:18,760 time between request was set to one 12378 08:53:18,760 --> 08:53:21,718 minute in that case every one minute a 12379 08:53:21,718 --> 08:53:23,558 value would be sent across the channel 12380 08:53:23,558 --> 08:53:25,920 so by using this syntax here we could 12381 08:53:25,920 --> 08:53:29,160 say run this for Loop every one minute 12382 08:53:29,160 --> 08:53:32,160 and the reason I'm passing in an empty 12383 08:53:32,160 --> 08:53:34,878 initializes and an empty um middle 12384 08:53:34,878 --> 08:53:36,798 section to the for Loop is so that it 12385 08:53:36,798 --> 08:53:39,318 executes immediately the first time so 12386 08:53:39,318 --> 08:53:41,520 the very first time we get to line 17 12387 08:53:41,520 --> 08:53:43,840 the body of the for Loop will requ will 12388 08:53:43,840 --> 08:53:47,280 will fire immediately and then it will 12389 08:53:47,280 --> 08:53:50,160 wait for the for the uh interval on the 12390 08:53:50,160 --> 08:53:52,000 ticker if that makes sense if we just 12391 08:53:52,000 --> 08:53:55,878 did this oops if we just did what is it 12392 08:53:55,878 --> 08:53:57,680 for 12393 08:53:57,680 --> 08:54:00,680 range tier. C uh then it would actually 12394 08:54:00,680 --> 08:54:02,200 wait for the minute up front but I want 12395 08:54:02,200 --> 08:54:04,680 to do it once immediately um it'll make 12396 08:54:04,680 --> 08:54:06,798 it easier to debug and work with now at 12397 08:54:06,798 --> 08:54:08,638 this point I realized that I've made a 12398 08:54:08,638 --> 08:54:11,520 mistake the purpose of this concurrency 12399 08:54:11,520 --> 08:54:13,920 parameter here is to uh you know 12400 08:54:13,920 --> 08:54:16,318 indicate to the start scraping function 12401 08:54:16,318 --> 08:54:18,360 how many go routines we want to use to 12402 08:54:18,360 --> 08:54:21,478 go fetch um all these different feeds 12403 08:54:21,478 --> 08:54:23,160 and the whole point is that we can fetch 12404 08:54:23,160 --> 08:54:25,680 them at the same time time so that means 12405 08:54:25,680 --> 08:54:27,718 that each time that this ticker fires we 12406 08:54:27,718 --> 08:54:29,878 need to be potentially go you know going 12407 08:54:29,878 --> 08:54:33,760 out to the internet to fetch 10 20 30 12408 08:54:33,760 --> 08:54:36,318 different RSS feeds and download all of 12409 08:54:36,318 --> 08:54:39,160 their blog posts at the same time which 12410 08:54:39,160 --> 08:54:42,000 means we'll actually need to be able to 12411 08:54:42,000 --> 08:54:44,520 grab a multiple number of feeds we'll 12412 08:54:44,520 --> 08:54:47,040 need to grab more than just one at a 12413 08:54:47,040 --> 08:54:48,920 time so rather than get next feed to 12414 08:54:48,920 --> 08:54:51,120 fetch let's change this to get next 12415 08:54:51,120 --> 08:54:54,000 feeds to fetch and we'll have it return 12416 08:54:54,000 --> 08:54:54,920 many 12417 08:54:54,920 --> 08:54:56,798 and then rather than limiting to one 12418 08:54:56,798 --> 08:54:59,440 let's limit to dollar sign one so we can 12419 08:54:59,440 --> 08:55:03,280 actually pass in how many feeds we want 12420 08:55:03,280 --> 08:55:06,000 as a parameter to this function okay 12421 08:55:06,000 --> 08:55:10,398 then we should be able to regenerate 12422 08:55:12,558 --> 08:55:15,760 that and we should oh we're not even 12423 08:55:15,760 --> 08:55:17,878 using the function yet so okay so that 12424 08:55:17,878 --> 08:55:19,840 was actually the perfect time to do that 12425 08:55:19,840 --> 08:55:21,558 okay let's fill out the body of this for 12426 08:55:21,558 --> 08:55:23,958 Loop so every interval time between 12427 08:55:23,958 --> 08:55:26,638 request we want to go grab the next 12428 08:55:26,638 --> 08:55:28,558 batch of feeds to fetch so we can just 12429 08:55:28,558 --> 08:55:30,478 call that function that we just wrote 12430 08:55:30,478 --> 08:55:33,878 database. getet next feeds to fetch it 12431 08:55:33,878 --> 08:55:37,558 takes a context and a limit so the first 12432 08:55:37,558 --> 08:55:41,318 thing we'll just use context. background 12433 08:55:41,318 --> 08:55:43,280 so again I haven't gone into a ton of 12434 08:55:43,280 --> 08:55:45,318 detail on the context package but 12435 08:55:45,318 --> 08:55:47,478 basically context. background is like 12436 08:55:47,478 --> 08:55:50,000 the global context it's what you use if 12437 08:55:50,000 --> 08:55:51,760 you don't have access to a scoped 12438 08:55:51,760 --> 08:55:54,360 context like we do for our individual 12439 08:55:54,360 --> 08:55:57,120 TTP requests okay so that'll work for 12440 08:55:57,120 --> 08:55:59,520 now and then we also need to pass in a 12441 08:55:59,520 --> 08:56:03,638 limit so we'll just cast int 32 and the 12442 08:56:03,638 --> 08:56:07,160 limit or the sorry the 12443 08:56:08,920 --> 08:56:11,478 concurrency and that should return some 12444 08:56:11,478 --> 08:56:14,200 feeds and an 12445 08:56:16,200 --> 08:56:18,360 err if there's an error we should 12446 08:56:18,360 --> 08:56:22,040 probably print something 12447 08:56:31,478 --> 08:56:33,840 now notice I'm continuing here that's 12448 08:56:33,840 --> 08:56:36,600 because this function should always be 12449 08:56:36,600 --> 08:56:39,040 running as our 12450 08:56:39,040 --> 08:56:42,000 server operates like there's no time in 12451 08:56:42,000 --> 08:56:44,080 which we want this function to ever stop 12452 08:56:44,080 --> 08:56:45,638 so if I returned here that would be a 12453 08:56:45,638 --> 08:56:47,638 problem it would actually stop scraping 12454 08:56:47,638 --> 08:56:49,200 completely just because maybe I don't 12455 08:56:49,200 --> 08:56:50,760 know our database connection was down 12456 08:56:50,760 --> 08:56:52,558 temporarily so for now we're just going 12457 08:56:52,558 --> 08:56:55,478 to log and continue now that we have a 12458 08:56:55,478 --> 08:56:57,878 slice of feeds let's write some logic 12459 08:56:57,878 --> 08:56:59,718 that goes and fetches each feed 12460 08:56:59,718 --> 08:57:01,958 individually and importantly fetches 12461 08:57:01,958 --> 08:57:05,318 each individually at the same time so 12462 08:57:05,318 --> 08:57:07,000 we're going to need a synchronization 12463 08:57:07,000 --> 08:57:08,798 mechanism uh I'm going to use a weight 12464 08:57:08,798 --> 08:57:11,360 group so the standard library has this 12465 08:57:11,360 --> 08:57:15,080 awesome thing called a sync. weight 12466 08:57:15,120 --> 08:57:17,600 group then we can iterate over all of 12467 08:57:17,600 --> 08:57:24,798 the feeds so four feed range feeds 12468 08:57:26,120 --> 08:57:27,878 okay so the way that the weight group 12469 08:57:27,878 --> 08:57:31,080 works is anytime you want to spawn a new 12470 08:57:31,080 --> 08:57:33,280 go routine within the context of the 12471 08:57:33,280 --> 08:57:37,080 weight group you do a weight group. add 12472 08:57:37,080 --> 08:57:39,440 and you add some number to it so here 12473 08:57:39,440 --> 08:57:41,718 I'm iterating over all of the feeds that 12474 08:57:41,718 --> 08:57:43,558 we want to fetch on individual go 12475 08:57:43,558 --> 08:57:45,798 routines and I'm going to add one to the 12476 08:57:45,798 --> 08:57:46,760 weight 12477 08:57:46,760 --> 08:57:49,680 group then at the end of the loop I can 12478 08:57:49,680 --> 08:57:52,958 do a weight group. 12479 08:57:52,958 --> 08:57:56,398 weight and and within the loop I can 12480 08:57:56,398 --> 08:57:58,600 spawn a new go routine so we're going to 12481 08:57:58,600 --> 08:58:01,318 go do some function in fact I guess I 12482 08:58:01,318 --> 08:58:03,238 should just name it kind of what we'll 12483 08:58:03,238 --> 08:58:07,718 be doing uh let's call it scrape feed go 12484 08:58:07,718 --> 08:58:10,798 scrape feed and here we're actually 12485 08:58:10,798 --> 08:58:13,680 going to pass the weight group in as one 12486 08:58:13,680 --> 08:58:14,520 of the 12487 08:58:14,520 --> 08:58:17,318 parameters and 12488 08:58:17,318 --> 08:58:20,360 within scrape 12489 08:58:20,360 --> 08:58:23,000 bead takes a weight group which is a 12490 08:58:23,000 --> 08:58:25,478 pointer to a 12491 08:58:25,478 --> 08:58:28,238 sync. weight 12492 08:58:28,238 --> 08:58:31,318 group within this function we'll defer a 12493 08:58:31,318 --> 08:58:33,360 weight group. 12494 08:58:33,360 --> 08:58:38,080 done okay so what happens here 12495 08:58:38,080 --> 08:58:40,878 basically we're iterating over the the 12496 08:58:40,878 --> 08:58:43,958 the all of the feeds on the same go 12497 08:58:43,958 --> 08:58:45,958 routine as the you know the start 12498 08:58:45,958 --> 08:58:49,280 scraping uh function so on the main go 12499 08:58:49,280 --> 08:58:52,080 routine on the main go routine we are 12500 08:58:52,080 --> 08:58:54,920 adding one to the weight group for every 12501 08:58:54,920 --> 08:58:57,238 feed right so say we had a concurrency 12502 08:58:57,238 --> 08:59:00,440 of 30 we would be adding 30 to the 12503 08:59:00,440 --> 08:59:03,600 weight group now we'll be spawning all 12504 08:59:03,600 --> 08:59:06,160 of these separate go routines as we do 12505 08:59:06,160 --> 08:59:07,878 that and when we get to the end of the 12506 08:59:07,878 --> 08:59:10,238 loop we're going to be waiting on the 12507 08:59:10,238 --> 08:59:14,318 weight group for 30 30 12508 08:59:14,318 --> 08:59:18,440 distinct calls to done so done 12509 08:59:18,440 --> 08:59:21,160 effectively decrements the counter by 12510 08:59:21,160 --> 08:59:23,398 one right done decrements the counter by 12511 08:59:23,398 --> 08:59:26,000 one so we're adding one every time we 12512 08:59:26,000 --> 08:59:28,440 iterate over the slice and then we're 12513 08:59:28,440 --> 08:59:30,360 calling done when we're done actually 12514 08:59:30,360 --> 08:59:32,520 scraping the feed so what this does is 12515 08:59:32,520 --> 08:59:35,440 it allows us to call scrape feed at the 12516 08:59:35,440 --> 08:59:38,920 same time 30 times we go spawn 30 12517 08:59:38,920 --> 08:59:41,120 different go routines to scrape 30 12518 08:59:41,120 --> 08:59:42,600 different RSS 12519 08:59:42,600 --> 08:59:47,558 feeds and when they're all done line 35 12520 08:59:47,558 --> 08:59:49,680 will kind of execute and we'll move past 12521 08:59:49,680 --> 08:59:51,760 that until they're like before they're 12522 08:59:51,760 --> 08:59:53,840 done we'll be blocking on line 35 which 12523 08:59:53,840 --> 08:59:55,360 is what we want to do because we don't 12524 08:59:55,360 --> 08:59:57,318 want to continue on to the next 12525 08:59:57,318 --> 09:00:00,558 iteration of the loop until we are sure 12526 09:00:00,558 --> 09:00:02,478 that we've actually scraped all of the 12527 09:00:02,478 --> 09:00:05,000 feeds so we've sort of stubbed out this 12528 09:00:05,000 --> 09:00:06,160 scrape feed function right now it 12529 09:00:06,160 --> 09:00:07,718 doesn't do anything other than call 12530 09:00:07,718 --> 09:00:09,760 weight group. let's actually go scrape 12531 09:00:09,760 --> 09:00:12,600 some feeds so it's going to need access 12532 09:00:12,600 --> 09:00:14,280 to a database 12533 09:00:14,280 --> 09:00:17,160 connection and it's also going to need a 12534 09:00:17,160 --> 09:00:20,080 specific feed to go fetch so feed is a 12535 09:00:20,080 --> 09:00:24,238 datab base. feed 12536 09:00:24,238 --> 09:00:26,760 cool and then here we can pass in 12537 09:00:26,760 --> 09:00:29,478 database and 12538 09:00:29,478 --> 09:00:33,238 feed great the first thing scrape feed 12539 09:00:33,238 --> 09:00:35,280 should do and and keep in mind we're 12540 09:00:35,280 --> 09:00:37,000 deferring the weight group. dun so this 12541 09:00:37,000 --> 09:00:40,000 will always be called at the end of this 12542 09:00:40,000 --> 09:00:41,878 function um the first thing we should do 12543 09:00:41,878 --> 09:00:44,160 is Mark that we've fetched this feed or 12544 09:00:44,160 --> 09:00:45,958 that we're fetching this feed so it's 12545 09:00:45,958 --> 09:00:47,958 going to be database. Mark feed as 12546 09:00:47,958 --> 09:00:50,600 fetched we can just use the background 12547 09:00:50,600 --> 09:00:52,920 context 12548 09:00:52,920 --> 09:00:55,558 again and we need the ID of the feed so 12549 09:00:55,558 --> 09:00:58,120 feed dot 12550 09:00:58,120 --> 09:01:01,398 ID cool that should return an error if 12551 09:01:01,398 --> 09:01:03,318 there was an error I think oh it also 12552 09:01:03,318 --> 09:01:04,920 Returns the updated feed I don't think 12553 09:01:04,920 --> 09:01:06,238 we care about the updated feed so I 12554 09:01:06,238 --> 09:01:08,440 think we can ignore 12555 09:01:08,440 --> 09:01:12,080 that say if air is not equal nil now 12556 09:01:12,080 --> 09:01:13,600 keep in mind we are not returning 12557 09:01:13,600 --> 09:01:14,958 anything from this function remember 12558 09:01:14,958 --> 09:01:16,840 we're calling it on a new go routine so 12559 09:01:16,840 --> 09:01:18,120 there's nothing to return here if 12560 09:01:18,120 --> 09:01:19,638 there's an error instead we'll just log 12561 09:01:19,638 --> 09:01:23,040 there was an issue 12562 09:01:31,318 --> 09:01:34,200 and return nothing and next we need to 12563 09:01:34,200 --> 09:01:35,478 actually do the heavy lifting which is 12564 09:01:35,478 --> 09:01:37,318 to go out and scrape the feed so we 12565 09:01:37,318 --> 09:01:39,958 already wrote Our URL to feed function 12566 09:01:39,958 --> 09:01:43,958 let's just use that so URL to feed and 12567 09:01:43,958 --> 09:01:47,200 we'll pass in the feed. URL and we 12568 09:01:47,200 --> 09:01:52,238 should get back an RSS feed and an 12569 09:01:52,238 --> 09:01:56,958 air and if error does not equal 12570 09:02:00,520 --> 09:02:04,600 nil error fetching 12571 09:02:06,958 --> 09:02:09,920 feed and we'll return 12572 09:02:09,920 --> 09:02:13,638 there otherwise we need to do 12573 09:02:13,638 --> 09:02:17,120 some logging so in the future what we'll 12574 09:02:17,120 --> 09:02:19,958 do is instead of iterating over all of 12575 09:02:19,958 --> 09:02:23,718 the um items in the RSS struct that we 12576 09:02:23,718 --> 09:02:25,160 get get back and just printing them to 12577 09:02:25,160 --> 09:02:27,280 the console we'll be saving them into 12578 09:02:27,280 --> 09:02:29,558 the database but for now just so that we 12579 09:02:29,558 --> 09:02:33,200 can test our scrape feed function um 12580 09:02:33,200 --> 09:02:34,840 we're just going to log log all of this 12581 09:02:34,840 --> 09:02:37,238 to the console so we're going to log um 12582 09:02:37,238 --> 09:02:39,280 each individual post or rather that we 12583 09:02:39,280 --> 09:02:42,160 found a post um and then how many posts 12584 09:02:42,160 --> 09:02:45,360 we found the last thing we need to do is 12585 09:02:45,360 --> 09:02:47,638 go hook up this start scraping function 12586 09:02:47,638 --> 09:02:49,840 to our main function so that it actually 12587 09:02:49,840 --> 09:02:52,798 starts okay so start scraping takes 12588 09:02:52,798 --> 09:02:54,280 database concurrency actually I'll just 12589 09:02:54,280 --> 09:02:56,558 open this uh my screen's too small to be 12590 09:02:56,558 --> 09:02:59,600 working in two tabs at the same time 12591 09:02:59,600 --> 09:03:01,600 okay um we're going to need to call it 12592 09:03:01,600 --> 09:03:04,440 before listen and serve because remember 12593 09:03:04,440 --> 09:03:06,680 this is where our server kind of blocks 12594 09:03:06,680 --> 09:03:09,040 and waits forever for incoming requests 12595 09:03:09,040 --> 09:03:10,798 so we should probably call it I don't 12596 09:03:10,798 --> 09:03:12,840 know 12597 09:03:12,840 --> 09:03:16,160 right here seems like a good 12598 09:03:16,160 --> 09:03:19,760 spot so um it's just it's just a 12599 09:03:19,760 --> 09:03:21,760 function right yeah it's not a method 12600 09:03:21,760 --> 09:03:23,478 takes database concurrency and time 12601 09:03:23,478 --> 09:03:27,478 between request okay so we go go start 12602 09:03:27,478 --> 09:03:28,840 scraping remember we want to call it on 12603 09:03:28,840 --> 09:03:31,120 a new go routine so it doesn't interrupt 12604 09:03:31,120 --> 09:03:33,558 uh this main flow because remember start 12605 09:03:33,558 --> 09:03:35,360 scraping is never going to return it's a 12606 09:03:35,360 --> 09:03:37,478 long running function uh this is an 12607 09:03:37,478 --> 09:03:41,160 infinite for Loop okay it needs a 12608 09:03:41,160 --> 09:03:42,200 database connection so we'll actually 12609 09:03:42,200 --> 09:03:44,638 need to save this 12610 09:03:44,638 --> 09:03:48,600 in a new variable so that we can use it 12611 09:03:48,600 --> 09:03:50,280 in the API config and in the start 12612 09:03:50,280 --> 09:03:52,000 scraping 12613 09:03:52,000 --> 09:03:55,878 function next we need the currency um 12614 09:03:55,878 --> 09:03:58,238 let's just start with 10 seems good and 12615 09:03:58,238 --> 09:04:00,000 then time between requests let's do 12616 09:04:00,000 --> 09:04:02,398 time. 12617 09:04:02,398 --> 09:04:05,680 minute perfect I went ahead and added a 12618 09:04:05,680 --> 09:04:07,558 second RSS feed so let's go ahead and 12619 09:04:07,558 --> 09:04:10,040 check the database and see what feeds we 12620 09:04:10,040 --> 09:04:13,040 have currently so I've got Lane's blog 12621 09:04:13,040 --> 09:04:15,000 and the boot Dev blog so there's two now 12622 09:04:15,000 --> 09:04:16,760 remember we were setting a concurrency 12623 09:04:16,760 --> 09:04:19,680 of 10 so we should definitely be able to 12624 09:04:19,680 --> 09:04:21,638 fetch both of these blogs at the same 12625 09:04:21,638 --> 09:04:24,558 time on the first iteration of that Loop 12626 09:04:24,558 --> 09:04:26,280 if we say deployed this production and 12627 09:04:26,280 --> 09:04:28,318 allowed users to start creating feeds 12628 09:04:28,318 --> 09:04:31,360 maybe we'd get up to 100 200 400 12629 09:04:31,360 --> 09:04:32,878 different feeds in here then we'd only 12630 09:04:32,878 --> 09:04:35,000 be fetching 10 at a time right just so 12631 09:04:35,000 --> 09:04:36,680 we understand how that mechanism works 12632 09:04:36,680 --> 09:04:38,000 but for now this should be good enough 12633 09:04:38,000 --> 09:04:40,360 to test I'm going to update our logs 12634 09:04:40,360 --> 09:04:42,958 just a bit um so that we can see which 12635 09:04:42,958 --> 09:04:45,680 blog each post is from so found post 12636 09:04:45,680 --> 09:04:47,200 item. 12637 09:04:47,200 --> 09:04:49,638 tile on 12638 09:04:49,638 --> 09:04:52,958 feed feed. name okay let's go ahead and 12639 09:04:52,958 --> 09:04:55,638 run that 12640 09:05:01,760 --> 09:05:03,638 bound post the property sub pointers in 12641 09:05:03,638 --> 09:05:07,360 go on feed boot Dev blog perfect we kind 12642 09:05:07,360 --> 09:05:09,318 of scroll up we should be able to see 12643 09:05:09,318 --> 09:05:12,718 some the boot Dev Blog has way more blog 12644 09:05:12,718 --> 09:05:16,040 posts than my personal blog here it is 12645 09:05:16,040 --> 09:05:18,360 here's some Lane's blog stuff okay so 12646 09:05:18,360 --> 09:05:19,958 that looks like it's working we should 12647 09:05:19,958 --> 09:05:21,558 be able to move on to the next step now 12648 09:05:21,558 --> 09:05:24,238 where we'll actually save these blog 12649 09:05:24,238 --> 09:05:26,760 posts into the database rather than just 12650 09:05:26,760 --> 09:05:29,120 logging the titles to the console we're 12651 09:05:29,120 --> 09:05:31,040 going to need a new table in our 12652 09:05:31,040 --> 09:05:33,520 database so let's start there we'll call 12653 09:05:33,520 --> 09:05:34,360 it 12654 09:05:34,360 --> 09:05:37,878 posts so the purpose of this table is to 12655 09:05:37,878 --> 09:05:39,238 store all of the posts that we are 12656 09:05:39,238 --> 09:05:42,318 fetching from all of the different uh 12657 09:05:42,318 --> 09:05:45,558 from all of the different RSS feeds okay 12658 09:05:45,558 --> 09:05:47,120 um what am I doing this is this is 12659 09:05:47,120 --> 09:05:49,080 queries we need to start with a 12660 09:05:49,080 --> 09:05:52,160 migration so let's grab this we'll make 12661 09:05:52,160 --> 09:05:55,318 it 006 12662 09:05:55,638 --> 09:05:57,958 posts. 12663 09:05:57,958 --> 09:06:00,760 SQL all right Goose up is going to be 12664 09:06:00,760 --> 09:06:02,520 create table 12665 09:06:02,520 --> 09:06:06,360 posts what goes in a posts table um we 12666 09:06:06,360 --> 09:06:08,398 are going to need an ID created at an 12667 09:06:08,398 --> 09:06:10,078 updated at that pretty much never 12668 09:06:10,078 --> 09:06:13,000 changes um what else does a post have 12669 09:06:13,000 --> 09:06:15,680 well it has a 12670 09:06:16,078 --> 09:06:17,918 title 12671 09:06:17,918 --> 09:06:21,398 title um is that text. null that makes 12672 09:06:21,398 --> 09:06:24,438 sense uh posts also typically have a 12673 09:06:24,438 --> 09:06:26,558 description text um I'm going to allow 12674 09:06:26,558 --> 09:06:28,000 that one to be nullable I think it's 12675 09:06:28,000 --> 09:06:29,960 okay if a post is missing its 12676 09:06:29,960 --> 09:06:32,918 description posts also typically have a 12677 09:06:32,918 --> 09:06:37,398 published at date so published at is a 12678 09:06:37,398 --> 09:06:39,398 timestamp um should we allow that one to 12679 09:06:39,398 --> 09:06:40,320 be 12680 09:06:40,320 --> 09:06:43,558 nullable no no let's make that not 12681 09:06:43,558 --> 09:06:47,398 null what else does a post have it has a 12682 09:06:47,398 --> 09:06:52,078 URL a URL should be not null for 12683 09:06:52,078 --> 09:06:54,398 sure um I'm also going to say that it 12684 09:06:54,398 --> 09:06:55,598 should be 12685 09:06:55,598 --> 09:06:57,200 unique 12686 09:06:57,200 --> 09:06:59,680 unique I don't think we ever want to 12687 09:06:59,680 --> 09:07:03,718 store the same Post in the database 12688 09:07:03,718 --> 09:07:06,520 twice there's no point right if we have 12689 09:07:06,520 --> 09:07:08,598 a post I don't see why we would need it 12690 09:07:08,598 --> 09:07:10,078 a second time so let's let's go ahead 12691 09:07:10,078 --> 09:07:12,680 and make that one unique and then lastly 12692 09:07:12,680 --> 09:07:15,398 let's just put in a feed 12693 09:07:15,398 --> 09:07:18,320 ID and the feed ID is going to be a uu 12694 09:07:18,320 --> 09:07:21,480 ID that 12695 09:07:21,480 --> 09:07:24,160 uh we're gonna want it to be a reference 12696 09:07:24,160 --> 09:07:25,640 so 12697 09:07:25,640 --> 09:07:29,122 references um feeds 12698 09:07:29,122 --> 09:07:32,960 ID right and that's going to 12699 09:07:32,960 --> 09:07:35,680 be does that need to be unique it 12700 09:07:35,680 --> 09:07:36,878 doesn't need to be unique but it should 12701 09:07:36,878 --> 09:07:39,480 be not null we should always have the 12702 09:07:39,480 --> 09:07:43,800 feed ID of a post and let's here put on 12703 09:07:43,800 --> 09:07:46,238 delete Cascade if we delete a feed we'll 12704 09:07:46,238 --> 09:07:48,078 Cascade and delete all of its posts and 12705 09:07:48,078 --> 09:07:50,438 I forgot to put the type here so URL 12706 09:07:50,438 --> 09:07:53,238 text. nil unique okay that looks good to 12707 09:07:53,238 --> 09:07:55,480 me let's go ahead and run our migration 12708 09:07:55,480 --> 09:07:58,718 so it's going to be uh we need to CD 12709 09:07:58,718 --> 09:08:01,000 into SQL 12710 09:08:01,000 --> 09:08:06,078 schema and run Goose 12711 09:08:06,078 --> 09:08:10,238 postgress we'll need this connection 12712 09:08:11,878 --> 09:08:14,278 string 12713 09:08:14,278 --> 09:08:17,480 up perfect next we'll need a couple of 12714 09:08:17,480 --> 09:08:19,598 queries to interact with this table uh 12715 09:08:19,598 --> 09:08:21,160 the first one's going to be just a way 12716 09:08:21,160 --> 09:08:24,160 to create a post so let's do posts 12717 09:08:24,160 --> 09:08:25,438 and we'll 12718 09:08:25,438 --> 09:08:26,960 do 12719 09:08:26,960 --> 09:08:28,520 create 12720 09:08:28,520 --> 09:08:33,598 oops create post return one thing and 12721 09:08:33,598 --> 09:08:35,598 we'll just kind of be inserting a bunch 12722 09:08:35,598 --> 09:08:37,480 of stuff I think let's take a look at 12723 09:08:37,480 --> 09:08:39,200 the post table so we've got ID created 12724 09:08:39,200 --> 09:08:41,718 at update at let me just grab this so I 12725 09:08:41,718 --> 09:08:44,238 don't forget 12726 09:08:47,480 --> 09:08:51,640 it okay so insert into 12727 09:08:51,640 --> 09:08:54,520 posts ID created updated 12728 09:08:54,520 --> 09:08:57,438 at we also have we have a lot of stuff 12729 09:08:57,438 --> 09:08:58,960 so I'm actually going to start spacing 12730 09:08:58,960 --> 09:09:00,238 this out a little 12731 09:09:00,238 --> 09:09:05,840 bit cre at update at it's going to be a 12732 09:09:06,360 --> 09:09:10,800 title and a 12733 09:09:14,238 --> 09:09:16,680 description publish 12734 09:09:16,680 --> 09:09:18,718 that 12735 09:09:18,718 --> 09:09:23,438 URL and a feed ID 12736 09:09:23,558 --> 09:09:28,078 okay and the values 1 2 3 4 how many do 12737 09:09:28,078 --> 09:09:31,160 we got just 12738 09:09:31,160 --> 09:09:33,040 eight 12739 09:09:33,040 --> 09:09:36,598 five 6 12740 09:09:36,598 --> 09:09:40,480 7 eight returning 12741 09:09:40,480 --> 09:09:42,878 star straightforward right insert into 12742 09:09:42,878 --> 09:09:47,078 posts all of these fields no fancy logic 12743 09:09:47,078 --> 09:09:50,360 that should be good okay let's run sqlc 12744 09:09:50,360 --> 09:09:53,520 generate to add that function to our 12745 09:09:53,520 --> 09:09:55,878 internal package and then we just need 12746 09:09:55,878 --> 09:09:58,960 to go use it so down in the scraper now 12747 09:09:58,960 --> 09:10:00,960 instead of just logging all of these 12748 09:10:00,960 --> 09:10:03,480 posts to the console let's save them to 12749 09:10:03,480 --> 09:10:05,960 the database um I'm going to leave this 12750 09:10:05,960 --> 09:10:08,840 log message it says feed blank collected 12751 09:10:08,840 --> 09:10:11,398 blank posts found so that'll just log 12752 09:10:11,398 --> 09:10:12,718 all of the different feeds we're 12753 09:10:12,718 --> 09:10:14,278 collecting but each individual post I 12754 09:10:14,278 --> 09:10:16,918 think it's wasteful and kind of busy to 12755 09:10:16,918 --> 09:10:18,320 log everything so we're not going to do 12756 09:10:18,320 --> 09:10:22,238 that instead we'll just call db. create 12757 09:10:22,238 --> 09:10:25,238 post context. 12758 09:10:25,238 --> 09:10:28,200 background and what does it take create 12759 09:10:28,200 --> 09:10:30,718 post prams database. create post prams 12760 09:10:30,718 --> 09:10:33,480 okay cool I kind of like how 12761 09:10:33,480 --> 09:10:38,000 sqlc breaks down the parameters into um 12762 09:10:38,000 --> 09:10:40,040 into a struct makes it pretty simple to 12763 09:10:40,040 --> 09:10:43,918 work with Okay um we've got an ID 12764 09:10:43,918 --> 09:10:46,438 created at updated at okay um ID is just 12765 09:10:46,438 --> 09:10:50,558 going to be a new ID 12766 09:10:53,640 --> 09:10:55,122 created at updated at that'll just be 12767 09:10:55,122 --> 09:10:57,078 time. 12768 09:10:57,078 --> 09:11:00,078 now 12769 09:11:05,598 --> 09:11:11,718 UTC what's next title description 12770 09:11:14,238 --> 09:11:17,200 tile item. 12771 09:11:17,200 --> 09:11:20,278 tile I just realized I just realized now 12772 09:11:20,278 --> 09:11:22,480 that I'm not putting the field names 12773 09:11:22,480 --> 09:11:25,238 it's kind of 12774 09:11:27,122 --> 09:11:31,398 embarrassing okay title 12775 09:11:33,800 --> 09:11:35,480 description do they not have a 12776 09:11:35,480 --> 09:11:38,438 description what does an item 12777 09:11:38,438 --> 09:11:42,758 have let's take a look at an item items 12778 09:11:42,758 --> 09:11:45,320 have title link description yeah it does 12779 09:11:45,320 --> 09:11:47,558 have a description what am I messing up 12780 09:11:47,558 --> 09:11:49,800 here can I use item. description 12781 09:11:49,800 --> 09:11:52,122 variable of type string as SQL n string 12782 09:11:52,122 --> 09:11:53,758 ah right okay 12783 09:11:53,758 --> 09:11:56,960 so we need to do SQL do null string a 12784 09:11:56,960 --> 09:11:58,800 null string has the string itself and 12785 09:11:58,800 --> 09:12:01,000 whether or not it's valid so we just uh 12786 09:12:01,000 --> 09:12:03,398 put in the string and then we say it is 12787 09:12:03,398 --> 09:12:08,160 valid string do valid is a bolean 12788 09:12:08,160 --> 09:12:10,558 true although actually this is a problem 12789 09:12:10,558 --> 09:12:13,122 right this is a problem because if item. 12790 09:12:13,122 --> 09:12:14,960 description is blank if it's an empty 12791 09:12:14,960 --> 09:12:16,558 string we're going to be putting in an 12792 09:12:16,558 --> 09:12:19,360 empty string and saying that it's there 12793 09:12:19,360 --> 09:12:22,360 even though it's not so let's not do 12794 09:12:22,360 --> 09:12:25,558 this let's do something a little 12795 09:12:25,558 --> 09:12:27,598 different let's 12796 09:12:27,598 --> 09:12:29,200 go 12797 09:12:29,200 --> 09:12:33,520 description is a new sq. 12798 09:12:35,878 --> 09:12:38,558 nring why is why is that giving me 12799 09:12:38,558 --> 09:12:40,878 trouble oh because because I'm doing it 12800 09:12:40,878 --> 09:12:42,758 within the call to create post do it 12801 09:12:42,758 --> 09:12:45,360 right here okay so we'll create a new 12802 09:12:45,360 --> 09:12:49,000 SQL n string and then we'll 12803 09:12:49,000 --> 09:12:53,438 say if item. description does not equal 12804 09:12:53,438 --> 09:12:57,122 the empty string then we get to set 12805 09:12:57,122 --> 09:13:01,278 description. string equal to item. 12806 09:13:01,278 --> 09:13:04,360 description and description. 12807 09:13:04,360 --> 09:13:06,320 valid equals 12808 09:13:06,320 --> 09:13:08,800 true and then we'll use the description 12809 09:13:08,800 --> 09:13:11,918 here does that make sense so if if the 12810 09:13:11,918 --> 09:13:14,160 item's description is blank then we'll 12811 09:13:14,160 --> 09:13:16,598 set the value to null in the database 12812 09:13:16,598 --> 09:13:20,480 effectively um otherwise we'll create 12813 09:13:20,480 --> 09:13:24,320 the valid uh description entity 12814 09:13:24,320 --> 09:13:27,200 okay next we need a publish 12815 09:13:27,200 --> 09:13:31,122 dat let's see we've got an item. pubdate 12816 09:13:31,122 --> 09:13:32,238 which is a string okay so we're going to 12817 09:13:32,238 --> 09:13:35,398 need to parse that string to parse that 12818 09:13:35,398 --> 09:13:38,598 date there is a time. parse function in 12819 09:13:38,598 --> 09:13:40,558 the standard library and we're going to 12820 09:13:40,558 --> 09:13:43,360 use this RFC 111 12821 09:13:43,360 --> 09:13:46,278 23z layout so this is the layout that 12822 09:13:46,278 --> 09:13:48,360 I'm using on the boot Dev blog and on my 12823 09:13:48,360 --> 09:13:51,278 blog to be more robust and support all 12824 09:13:51,278 --> 09:13:53,878 of the different publishing format for 12825 09:13:53,878 --> 09:13:55,078 all the different blogs that we want to 12826 09:13:55,078 --> 09:13:57,040 scrip we'd probably need to make this 12827 09:13:57,040 --> 09:13:59,878 logic a little bit more robust but for 12828 09:13:59,878 --> 09:14:03,078 now I'm just going to say we're parsing 12829 09:14:03,078 --> 09:14:05,480 it this way if it's not that way I guess 12830 09:14:05,480 --> 09:14:09,078 we take a hike okay um if there's an 12831 09:14:09,078 --> 09:14:12,078 error so if error does not equal 12832 09:14:12,078 --> 09:14:16,918 nil we can say log. print 12833 09:14:18,398 --> 09:14:22,960 line parse date 12834 09:14:24,320 --> 09:14:29,960 sent V with air sent V and we'll pass in 12835 09:14:29,960 --> 09:14:32,078 the actual Pub 12836 09:14:32,078 --> 09:14:34,800 date and an error and that's going to be 12837 09:14:34,800 --> 09:14:35,878 a print 12838 09:14:35,878 --> 09:14:39,598 F oops cool and then if that's an issue 12839 09:14:39,598 --> 09:14:40,960 we'll just continue so if we don't get a 12840 09:14:40,960 --> 09:14:44,040 valid time uh then we'll just we'll just 12841 09:14:44,040 --> 09:14:45,878 log it log and move 12842 09:14:45,878 --> 09:14:50,160 on okay so published at pass in that I 12843 09:14:50,160 --> 09:14:51,800 shouldn't use single name variables like 12844 09:14:51,800 --> 09:14:55,480 this let's do Hub 12845 09:14:56,438 --> 09:15:00,160 at okay what else do we got a URL and a 12846 09:15:00,160 --> 09:15:01,840 feed ID so 12847 09:15:01,840 --> 09:15:05,558 URL is just going to be the item. 12848 09:15:05,558 --> 09:15:07,718 link and feed 12849 09:15:07,718 --> 09:15:11,640 ID do we have access to the feed ID 12850 09:15:11,640 --> 09:15:14,040 here we do we have the feed right 12851 09:15:14,040 --> 09:15:17,238 because we passed in the feed here 12852 09:15:17,238 --> 09:15:20,238 perfect 12853 09:15:21,480 --> 09:15:24,520 b.id now db. cre post does return an 12854 09:15:24,520 --> 09:15:27,878 error so we need to handle that 12855 09:15:27,878 --> 09:15:31,680 error what am I screwing up here oh it 12856 09:15:31,680 --> 09:15:33,960 also Returns the post itself I don't 12857 09:15:33,960 --> 09:15:35,238 think we care about the new post though 12858 09:15:35,238 --> 09:15:36,398 I think all we care about is if it 12859 09:15:36,398 --> 09:15:38,360 failed so if 12860 09:15:38,360 --> 09:15:41,680 error equal 12861 09:15:47,320 --> 09:15:51,238 nil fa to create post with 12862 09:15:51,238 --> 09:15:54,360 error oh okay let's give that a shot 12863 09:15:54,360 --> 09:15:57,122 okay build and 12864 09:15:57,278 --> 09:15:59,680 run now remember we're expecting this 12865 09:15:59,680 --> 09:16:01,680 time to get logs that just say that the 12866 09:16:01,680 --> 09:16:04,520 blogs were collected so 21 posts from 12867 09:16:04,520 --> 09:16:07,398 Lane's blog 321 posts from the boot Dev 12868 09:16:07,398 --> 09:16:09,360 blog were collected I'm going to go 12869 09:16:09,360 --> 09:16:11,360 ahead and kill the server and let's 12870 09:16:11,360 --> 09:16:14,520 check PG admin so now if we select star 12871 09:16:14,520 --> 09:16:15,640 from 12872 09:16:15,640 --> 09:16:18,598 Posts we should see a bunch of stuff in 12873 09:16:18,598 --> 09:16:23,520 here IDs created at titles descriptions 12874 09:16:23,520 --> 09:16:26,360 published at dates awesome this is 12875 09:16:26,360 --> 09:16:27,598 looking 12876 09:16:27,598 --> 09:16:30,078 fantastic we scroll down to see how many 12877 09:16:30,078 --> 09:16:32,520 rows there are 342 that looks right to 12878 09:16:32,520 --> 09:16:35,918 me now I think we have an issue here let 12879 09:16:35,918 --> 09:16:37,680 me show you what I mean if we run this 12880 09:16:37,680 --> 09:16:39,598 again so remember we've scraped both of 12881 09:16:39,598 --> 09:16:42,078 the feeds and pulled in all of the posts 12882 09:16:42,078 --> 09:16:44,480 so if I rerun my server at this 12883 09:16:44,480 --> 09:16:47,640 point yeah we're getting all of these 12884 09:16:47,640 --> 09:16:50,360 issues fail to create post duplicate key 12885 09:16:50,360 --> 09:16:52,438 value violates unique constraint posts 12886 09:16:52,438 --> 09:16:55,200 URL key right now this makes sense we 12887 09:16:55,200 --> 09:16:57,598 didn't want to store duplicate posts in 12888 09:16:57,598 --> 09:16:59,078 our database so we have a unique 12889 09:16:59,078 --> 09:17:01,278 constraint on the post URL which means 12890 09:17:01,278 --> 09:17:04,398 when we go try to recreate the posts it 12891 09:17:04,398 --> 09:17:06,078 fails because we already have the posts 12892 09:17:06,078 --> 09:17:08,878 in our database so let's do a little 12893 09:17:08,878 --> 09:17:11,800 string uh a string detection so that we 12894 09:17:11,800 --> 09:17:14,200 don't log this crap every time this 12895 09:17:14,200 --> 09:17:15,800 happens because this isn't really an 12896 09:17:15,800 --> 09:17:19,278 error this is expected Behavior so um we 12897 09:17:19,278 --> 09:17:21,360 can do something like 12898 09:17:21,360 --> 09:17:24,278 if string do 12899 09:17:24,278 --> 09:17:27,960 contains air. 12900 09:17:28,000 --> 09:17:30,420 error uh duplicate 12901 09:17:30,420 --> 09:17:31,718 [Music] 12902 09:17:31,718 --> 09:17:34,718 duplicate 12903 09:17:36,160 --> 09:17:39,000 e then do we continue what are we doing 12904 09:17:39,000 --> 09:17:42,480 here yeah then we 12905 09:17:42,480 --> 09:17:45,360 continue otherwise we'll log the eror so 12906 09:17:45,360 --> 09:17:47,480 we're only going to log the error if 12907 09:17:47,480 --> 09:17:50,918 it's not a duplicate key error okay so 12908 09:17:50,918 --> 09:17:53,598 let's run that again and make sure we 12909 09:17:53,598 --> 09:17:55,520 don't get those 12910 09:17:55,520 --> 09:17:59,398 errors perfect we have one last feature 12911 09:17:59,398 --> 09:18:01,598 to add to our RSS aggregator we need a 12912 09:18:01,598 --> 09:18:04,040 way for users to be able to get a list 12913 09:18:04,040 --> 09:18:06,598 of all of the newest posts from the 12914 09:18:06,598 --> 09:18:08,758 feeds that they're following so we'll 12915 09:18:08,758 --> 09:18:10,078 need a new 12916 09:18:10,078 --> 09:18:14,078 query uh we can call this 12917 09:18:14,438 --> 09:18:19,238 one get posts for user and it will 12918 09:18:19,238 --> 09:18:21,718 return many posts now let's think about 12919 09:18:21,718 --> 09:18:22,878 this query for a second it's a little 12920 09:18:22,878 --> 09:18:24,238 more complex than the other queries 12921 09:18:24,238 --> 09:18:25,438 we've done and that I think we need to 12922 09:18:25,438 --> 09:18:29,398 do a join so we have our posts 12923 09:18:29,398 --> 09:18:32,122 table right post have IDs created at 12924 09:18:32,122 --> 09:18:33,758 updated at but importantly they have a 12925 09:18:33,758 --> 09:18:37,558 feed ID so we know what feed every Post 12926 09:18:37,558 --> 09:18:39,878 in the database belongs to and we also 12927 09:18:39,878 --> 09:18:43,520 have a feed follows table that tells us 12928 09:18:43,520 --> 09:18:46,278 which feeds an individual user is 12929 09:18:46,278 --> 09:18:49,122 following so if we join those two tables 12930 09:18:49,122 --> 09:18:51,160 together right if we take all of the 12931 09:18:51,160 --> 09:18:53,558 feed follow information kind of join it 12932 09:18:53,558 --> 09:18:55,680 to the posts table then we should be 12933 09:18:55,680 --> 09:18:58,918 able to filter by all of the feeds that 12934 09:18:58,918 --> 09:19:00,960 a user is actually following so what 12935 09:19:00,960 --> 09:19:02,480 does that look 12936 09:19:02,480 --> 09:19:07,878 like you can do select posts. star so 12937 09:19:07,878 --> 09:19:09,640 everything from the post 12938 09:19:09,640 --> 09:19:12,640 table from 12939 09:19:12,640 --> 09:19:14,480 Posts 12940 09:19:14,480 --> 09:19:17,276 join feed 12941 09:19:17,276 --> 09:19:19,596 follows 12942 09:19:19,596 --> 09:19:26,320 on oops on post do feed ID equals feed 12943 09:19:26,320 --> 09:19:30,880 follows. feed ID okay so this adds 12944 09:19:30,880 --> 09:19:32,240 essentially all the feed follow 12945 09:19:32,240 --> 09:19:35,160 information to our like the virtual 12946 09:19:35,160 --> 09:19:37,520 table for this query right we're joining 12947 09:19:37,520 --> 09:19:38,840 those two tables together so now we 12948 09:19:38,840 --> 09:19:41,480 should be able to filter um the way we 12949 09:19:41,480 --> 09:19:44,000 want Okay so we've we've joined them 12950 09:19:44,000 --> 09:19:45,720 together uh 12951 09:19:45,720 --> 09:19:51,436 where posts dot wait posts no where feed 12952 09:19:51,436 --> 09:19:53,240 follows. user 12953 09:19:53,240 --> 09:19:55,276 ID 12954 09:19:55,276 --> 09:19:59,160 equals dollar sign one okay so we join 12955 09:19:59,160 --> 09:20:01,360 the tables and then we filter all the 12956 09:20:01,360 --> 09:20:04,360 posts down or rather the entire table 12957 09:20:04,360 --> 09:20:07,160 down by the specific user ID so all of 12958 09:20:07,160 --> 09:20:09,520 the posts that belong to feeds that the 12959 09:20:09,520 --> 09:20:11,680 user is not following should at this 12960 09:20:11,680 --> 09:20:14,360 step get trimmed 12961 09:20:14,360 --> 09:20:19,080 out then we can order by let's do post. 12962 09:20:19,080 --> 09:20:21,276 published at descending so it give us 12963 09:20:21,276 --> 09:20:24,200 the newest stuff first 12964 09:20:24,200 --> 09:20:26,756 and we'll limmit by a configurable 12965 09:20:26,756 --> 09:20:29,080 amount so dollar sign 12966 09:20:29,080 --> 09:20:32,720 two cool let's go ahead and try to 12967 09:20:32,720 --> 09:20:34,000 generate 12968 09:20:34,000 --> 09:20:37,000 that looks like it worked let's see if 12969 09:20:37,000 --> 09:20:38,520 uh see if when we run the actual 12970 09:20:38,520 --> 09:20:40,640 application it does what we expect let's 12971 09:20:40,640 --> 09:20:43,916 hook that query up to a new endpoint so 12972 09:20:43,916 --> 09:20:46,276 I'm here in the users file that seems 12973 09:20:46,276 --> 09:20:49,520 like a reasonable place we'll do 12974 09:20:49,520 --> 09:20:53,360 Handler get posts for user 12975 09:20:53,360 --> 09:20:55,320 it will be an authenticated endpoint so 12976 09:20:55,320 --> 09:20:58,480 we'll need that that user data um but 12977 09:20:58,480 --> 09:21:01,960 here we're going to call DB dot or sorry 12978 09:21:01,960 --> 09:21:03,400 API 12979 09:21:03,400 --> 09:21:08,400 config DB doget posts for user and then 12980 09:21:08,400 --> 09:21:13,040 we can pass in the request. context and 12981 09:21:13,040 --> 09:21:18,040 user. ID oh we also need I think a 12982 09:21:18,040 --> 09:21:21,276 limit oh get no no no sorry we take we 12983 09:21:21,276 --> 09:21:24,360 take database. get post for user params 12984 09:21:24,360 --> 09:21:25,756 right because we had multiple parameters 12985 09:21:25,756 --> 09:21:27,596 here so we'll need the user's ID and a 12986 09:21:27,596 --> 09:21:31,436 limit the user. ID and for now let's 12987 09:21:31,436 --> 09:21:33,480 just say a limit of 10 and that will 12988 09:21:33,480 --> 09:21:35,800 return to us some posts and potentially 12989 09:21:35,800 --> 09:21:37,560 an 12990 09:21:37,560 --> 09:21:41,320 error if we get an error we'll respond 12991 09:21:41,320 --> 09:21:42,800 with 12992 09:21:42,800 --> 09:21:46,040 it couldn't get 12993 09:21:46,040 --> 09:21:48,120 posts otherwise we need to return the 12994 09:21:48,120 --> 09:21:53,040 post themselves now we should go create 12995 09:21:53,040 --> 09:21:56,320 a special posts model right so that we 12996 09:21:56,320 --> 09:22:00,320 get our our own tag so type post 12997 09:22:00,320 --> 09:22:03,840 struct go mostly copy this 12998 09:22:03,840 --> 09:22:05,640 from our 12999 09:22:05,640 --> 09:22:07,596 internal post 13000 09:22:07,596 --> 09:22:11,880 model wherever it ended up here it 13001 09:22:14,640 --> 09:22:16,840 is 13002 09:22:16,840 --> 09:22:21,720 okay add some Json tags 13003 09:22:29,200 --> 09:22:32,800 goodness typing is 13004 09:22:46,840 --> 09:22:49,436 hard now here's an interesting 13005 09:22:49,436 --> 09:22:53,840 thing this SQL null string um is not 13006 09:22:53,840 --> 09:22:56,160 something that we're going to want to 13007 09:22:56,160 --> 09:22:59,240 use um in this struct because this is a 13008 09:22:59,240 --> 09:23:01,560 struct that Marshalls to Json the null 13009 09:23:01,560 --> 09:23:05,240 string object is a nested struct so if 13010 09:23:05,240 --> 09:23:07,480 we Marshal it directly to Json we would 13011 09:23:07,480 --> 09:23:10,040 actually get description as a Json key 13012 09:23:10,040 --> 09:23:12,160 and then string as a Json key and then 13013 09:23:12,160 --> 09:23:13,960 valid as a Json key so be a little 13014 09:23:13,960 --> 09:23:16,916 nested object there that's pretty bad 13015 09:23:16,916 --> 09:23:19,400 user experience because Json natively 13016 09:23:19,400 --> 09:23:21,680 supports kind of null in the sense that 13017 09:23:21,680 --> 09:23:24,800 you can just omit the the key um or use 13018 09:23:24,800 --> 09:23:28,200 like the actual value null um so what 13019 09:23:28,200 --> 09:23:30,400 we're going to do is instead do a 13020 09:23:30,400 --> 09:23:32,040 pointer to a 13021 09:23:32,040 --> 09:23:35,080 string and the way Json marshalling and 13022 09:23:35,080 --> 09:23:36,680 go works is if you have a pointer to a 13023 09:23:36,680 --> 09:23:39,040 string and it is nil then it will 13024 09:23:39,040 --> 09:23:40,916 Marshal to what you'd expect in Json 13025 09:23:40,916 --> 09:23:42,880 land which is that null 13026 09:23:42,880 --> 09:23:47,240 value okay then publish 13027 09:23:49,080 --> 09:23:53,080 that URL 13028 09:23:53,436 --> 09:23:55,680 and feed 13029 09:23:55,680 --> 09:23:58,480 ID okay did I miss anything let me look 13030 09:23:58,480 --> 09:24:00,000 over this really 13031 09:24:00,000 --> 09:24:02,840 quick that's looking 13032 09:24:02,840 --> 09:24:06,960 good and next we need the conversion so 13033 09:24:06,960 --> 09:24:08,880 we'll 13034 09:24:08,880 --> 09:24:14,680 do database post to post 13035 09:24:44,320 --> 09:24:46,756 now this one gets a little hairy right 13036 09:24:46,756 --> 09:24:48,400 um we probably need to do some logic 13037 09:24:48,400 --> 09:24:53,756 here so we'll say bar description 13038 09:24:53,756 --> 09:24:55,400 pointer to a 13039 09:24:55,400 --> 09:24:58,320 string and then if DB 13040 09:24:58,320 --> 09:25:01,640 post. description. 13041 09:25:01,640 --> 09:25:05,756 valid then we'll set description equal 13042 09:25:05,756 --> 09:25:10,160 to the address of DB post. description. 13043 09:25:10,160 --> 09:25:12,360 string cool then we can just directly 13044 09:25:12,360 --> 09:25:15,720 use the description variable 13045 09:25:15,720 --> 09:25:20,640 there all right published that 13046 09:25:25,200 --> 09:25:29,040 what else we got URL on Feed 13047 09:25:33,360 --> 09:25:36,520 ID okay and last but not least we need a 13048 09:25:36,520 --> 09:25:38,560 way to do it uh do the conversion for an 13049 09:25:38,560 --> 09:25:44,436 entire slice bunk DB or database posts 13050 09:25:44,436 --> 09:25:48,040 to posts 13051 09:25:58,400 --> 09:26:01,120 and the logic will look pretty much 13052 09:26:01,120 --> 09:26:02,596 identical to that but I actually think 13053 09:26:02,596 --> 09:26:04,000 it'll be easier to type it out so we'll 13054 09:26:04,000 --> 09:26:10,640 do uh posts slice post 13055 09:26:25,200 --> 09:26:28,160 it database post 13056 09:26:28,160 --> 09:26:31,840 post the database 13057 09:26:32,960 --> 09:26:34,720 post 13058 09:26:34,720 --> 09:26:37,436 okay there we 13059 09:26:37,436 --> 09:26:41,436 go lot of conversion logic there but now 13060 09:26:41,436 --> 09:26:44,160 we should be good to just respond with 13061 09:26:44,160 --> 09:26:44,960 some 13062 09:26:44,960 --> 09:26:48,000 Json and we can pass 13063 09:26:48,000 --> 09:26:51,880 in those posts as database posts cool 13064 09:26:51,880 --> 09:26:53,840 what am I get in 13065 09:26:53,840 --> 09:26:56,596 here truck literally uses unkeyed Fields 13066 09:26:56,596 --> 09:26:58,436 oh yeah let's not do 13067 09:26:58,436 --> 09:27:01,480 that we want an 13068 09:27:01,480 --> 09:27:05,480 ID and I think it's a 13069 09:27:06,320 --> 09:27:10,720 limit right what am I messing up user 13070 09:27:10,720 --> 09:27:12,680 ID 13071 09:27:12,680 --> 09:27:15,240 perfect okay let's build and run the 13072 09:27:15,240 --> 09:27:17,720 server 13073 09:27:18,916 --> 09:27:21,436 again oh I realize I made a mistake I 13074 09:27:21,436 --> 09:27:22,756 need to actually hook this up to 13075 09:27:22,756 --> 09:27:26,320 something so let's go back into main.go 13076 09:27:26,320 --> 09:27:28,640 we need a new 13077 09:27:28,640 --> 09:27:32,200 endpoint we'll do 13078 09:27:32,200 --> 09:27:36,080 get um I don't know user 13079 09:27:36,080 --> 09:27:38,916 feed now feed's probably a loaded term 13080 09:27:38,916 --> 09:27:40,960 in this uh in this application we should 13081 09:27:40,960 --> 09:27:43,400 say uh let's just do 13082 09:27:43,400 --> 09:27:45,960 posts and it's going to require 13083 09:27:45,960 --> 09:27:50,640 middleware so middleware off and API CFG 13084 09:27:50,640 --> 09:27:52,756 Dot 13085 09:27:52,756 --> 09:27:56,000 Handler get posts for user okay so get 13086 09:27:56,000 --> 09:27:58,436 SL posts it's an authenticated endpoint 13087 09:27:58,436 --> 09:28:02,276 Perfect all right let's rebuild and run 13088 09:28:02,680 --> 09:28:05,120 that 13089 09:28:05,120 --> 09:28:09,000 okay opening up thunder 13090 09:28:09,520 --> 09:28:13,520 client first we need to check well 13091 09:28:13,520 --> 09:28:16,436 actually let's just grab some off 13092 09:28:16,436 --> 09:28:19,320 information so 13093 09:28:19,320 --> 09:28:23,916 um this clearly has some 13094 09:28:23,916 --> 09:28:26,960 moth let's grab that API key create a 13095 09:28:26,960 --> 09:28:27,960 new 13096 09:28:27,960 --> 09:28:33,880 request HTTP col Local 13097 09:28:33,880 --> 09:28:37,360 Host V1 13098 09:28:37,360 --> 09:28:40,756 posts headers close 13099 09:28:40,756 --> 09:28:43,000 that 13100 09:28:43,000 --> 09:28:47,800 authorization API key okay so if I make 13101 09:28:47,800 --> 09:28:49,800 that request I'm getting back no posts 13102 09:28:49,800 --> 09:28:51,040 now we know we have posts in the 13103 09:28:51,040 --> 09:28:53,680 database but my my user that I'm 13104 09:28:53,680 --> 09:28:57,720 currently logged in as is not following 13105 09:28:57,720 --> 09:28:59,560 anything right I'm getting back the 13106 09:28:59,560 --> 09:29:03,436 empty array when I when I check my feed 13107 09:29:03,436 --> 09:29:06,480 follows um but I can check which feeds 13108 09:29:06,480 --> 09:29:09,720 Exist by running this API 13109 09:29:09,720 --> 09:29:12,880 request so let's grab this feed let's 13110 09:29:12,880 --> 09:29:16,080 grab the Wags Lane feed and let's go 13111 09:29:16,080 --> 09:29:18,916 follow that one so we'll post to feed 13112 09:29:18,916 --> 09:29:23,880 follows here this feed ID 13113 09:29:23,880 --> 09:29:25,840 okay so now I should be following let's 13114 09:29:25,840 --> 09:29:27,720 check my feed 13115 09:29:27,720 --> 09:29:30,720 follows great I'm following them so now 13116 09:29:30,720 --> 09:29:33,560 if I go get my 13117 09:29:35,596 --> 09:29:39,360 posts there we go I should just be 13118 09:29:39,360 --> 09:29:40,800 getting 13119 09:29:40,800 --> 09:29:45,276 posts from the Wags lane. Dead 13120 09:29:45,276 --> 09:29:49,400 Block perfect let's try following let's 13121 09:29:49,400 --> 09:29:52,320 try following um 13122 09:29:52,320 --> 09:29:55,240 the other one 13123 09:29:55,240 --> 09:29:59,080 so where is it feed follows no 13124 09:29:59,080 --> 09:30:01,596 feeds let's try following the boot Dev 13125 09:30:01,596 --> 09:30:02,596 blog as 13126 09:30:02,596 --> 09:30:07,560 well so post to feed 13127 09:30:08,400 --> 09:30:12,240 follows send that check my feed follows 13128 09:30:12,240 --> 09:30:15,120 now I'm following both now if I go get 13129 09:30:15,120 --> 09:30:16,160 my 13130 09:30:16,160 --> 09:30:18,480 posts perfect we're seeing stuff from 13131 09:30:18,480 --> 09:30:22,080 the boot Dev blog that's it thank than 13132 09:30:22,080 --> 09:30:24,840 you for sticking with me through all of 13133 09:30:24,840 --> 09:30:27,960 this mess we've created an amazing blog 13134 09:30:27,960 --> 09:30:30,276 aggregator that will actually work 13135 09:30:30,276 --> 09:30:32,800 pretty darn well at scale you could run 13136 09:30:32,800 --> 09:30:35,160 this thing uh you know over a long 13137 09:30:35,160 --> 09:30:37,680 period of time collect millions of blog 13138 09:30:37,680 --> 09:30:41,520 posts and it would do pretty well I hope 13139 09:30:41,520 --> 09:30:43,880 you had a ton of fun with this project I 13140 09:30:43,880 --> 09:30:46,520 do want to remind you that this is a 13141 09:30:46,520 --> 09:30:48,800 server right we've kind of been running 13142 09:30:48,800 --> 09:30:51,000 it stopping it restarting it but at the 13143 09:30:51,000 --> 09:30:53,640 end of the day you can just turn it on 13144 09:30:53,640 --> 09:30:56,560 ADD new feeds and follows and interact 13145 09:30:56,560 --> 09:30:58,720 with it directly and it will once a 13146 09:30:58,720 --> 09:31:01,436 minute go out and collect all of those 13147 09:31:01,436 --> 09:31:03,360 blog posts so you could just keep this 13148 09:31:03,360 --> 09:31:05,720 running on a Raspberry Pi in your house 13149 09:31:05,720 --> 09:31:08,960 um to aggregate you know blog posts 13150 09:31:08,960 --> 09:31:11,640 podcasts all that kind of stuff um I 13151 09:31:11,640 --> 09:31:13,160 will point out that we have done a bit 13152 09:31:13,160 --> 09:31:16,120 of happy path programming so happy path 13153 09:31:16,120 --> 09:31:17,520 programming is when you're not 13154 09:31:17,520 --> 09:31:19,880 necessarily handling every Edge case out 13155 09:31:19,880 --> 09:31:22,120 there you're you're handling kind of you 13156 09:31:22,120 --> 09:31:23,916 the thing that you expect to happen most 13157 09:31:23,916 --> 09:31:26,640 of the time so for example um we only 13158 09:31:26,640 --> 09:31:29,200 had one type of date parsing for the 13159 09:31:29,200 --> 09:31:32,400 published at dates in our RSS feeds but 13160 09:31:32,400 --> 09:31:34,160 maybe there are RSS feeds out there that 13161 09:31:34,160 --> 09:31:36,360 use a different date format and we'll 13162 09:31:36,360 --> 09:31:38,800 fail to parse them um so one way that 13163 09:31:38,800 --> 09:31:40,436 you could extend this project would be 13164 09:31:40,436 --> 09:31:43,520 to just add a ton of new RSS feeds and 13165 09:31:43,520 --> 09:31:45,596 make sure that you deal with the issues 13166 09:31:45,596 --> 09:31:47,560 as they come up make sure you improve 13167 09:31:47,560 --> 09:31:49,360 the logging so that you can see the 13168 09:31:49,360 --> 09:31:51,680 issues when they come up anyways I hope 13169 09:31:51,680 --> 09:31:53,720 you had a ton of fun with this project 13170 09:31:53,720 --> 09:31:55,840 and that you learned something I just 13171 09:31:55,840 --> 09:31:57,596 want to remind you that we do have an 13172 09:31:57,596 --> 09:32:00,436 entire backend learning path over on 13173 09:32:00,436 --> 09:32:03,276 boot. in Goan so if you liked this 13174 09:32:03,276 --> 09:32:04,880 project if you liked this course and are 13175 09:32:04,880 --> 09:32:07,276 looking for some more content definitely 13176 09:32:07,276 --> 09:32:10,080 go check out boot. we also have 13177 09:32:10,080 --> 09:32:11,276 published a lot of different ways that 13178 09:32:11,276 --> 09:32:13,276 you could potentially extend this 13179 09:32:13,276 --> 09:32:15,560 project to make it cooler for example 13180 09:32:15,560 --> 09:32:17,800 maybe you add a front end or a command 13181 09:32:17,800 --> 09:32:19,520 line application that interacts directly 13182 09:32:19,520 --> 09:32:20,880 with the API so that you don't need to 13183 09:32:20,880 --> 09:32:23,520 use manual client like thunder client 13184 09:32:23,520 --> 09:32:25,480 every time that you want to interact 13185 09:32:25,480 --> 09:32:27,916 with your posts and then I also just 13186 09:32:27,916 --> 09:32:29,916 want to remind you before I go that you 13187 09:32:29,916 --> 09:32:33,520 can find me on Twitter at Wags lane or 13188 09:32:33,520 --> 09:32:36,520 on YouTube at boot. definitely go 13189 09:32:36,520 --> 09:32:38,840 subscribe to our YouTube channel as well 13190 09:32:38,840 --> 09:32:40,520 thank you again to free code camp for 13191 09:32:40,520 --> 09:32:42,880 allowing us to publish this course and 13192 09:32:42,880 --> 09:32:45,040 this project walk through I hope you 13193 09:32:45,040 --> 09:32:46,520 enjoyed it and I'll see you in the next 13194 09:32:46,520 --> 09:32:48,960 one947227

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.